Editing and Sharing Home Videos with MediaGoblin

Michael Lynch

MediaGoblinでホームビデオを編集・共有する

原文は Michael Lynch により に公開されました。 このブログを購読する

目的

このチュートリアルでは、デジタル化したビデオキャプチャを小さなクリップに編集し、パスワードで保護された自前のMediaGoblinサーバーで公開する方法を紹介します。無料のHeroku dynoを使用するため、このプライベートなメディアサーバーを運用する継続的なコストはGoogle Cloud Storageのストレージ料金のみで、1GBあたり2.3セントです。

私はこのワークフローを使って家族のホームビデオを編集・共有しており、コストは月額わずか0.77ドルでした。詳しい経緯については、ブログ記事「My Eight-Year Quest to Digitize 45 Videotapes」をご覧ください。このワークフローは、切り出して共有したい多数のサブクリップを含むあらゆる種類の動画ファイルに利用できます。

前提条件

  • Python 3
  • virtualenv
  • Git
  • Docker
  • ffmpeg
  • 動画プレーヤー
    • 理想的にはAdobe Premiere ElementsやOpenShotのような編集タイムラインを備えたもの。
  • 無料のHerokuアカウント
  • Google Cloud Platformアカウント(請求が有効なもの)

デモ動画

例として、このチュートリアル全体で使用する動画は、1950年代のテキサスのある家族のパブリックドメインのホームビデオです。

このチュートリアルで編集・共有する素材として使用するパブリックドメインの動画(この動画には音声が含まれていないことに注意してください)

この動画をダウンロードするには、以下のコマンドを実行してください。

VIDEO_URL="https://github.com/mtlynch/free-usage-videos/blob/master/texas-farm-family-1952/TexasFar1952.mp4?raw=true"RAW_VIDEOS_DIR="${HOME}/videos-raw"RAW_VIDEO="${RAW_VIDEOS_DIR}/TexasFar1952.mp4"mkdir -p "$RAW_VIDEOS_DIR"wget "$VIDEO_URL" -O "$RAW_VIDEO"

アノテーションの付与

動画ファイルは一連のフレームで構成されています。動画ファイル内のクリップの開始位置と終了位置を特定するには、再生位置に対応するフレーム番号を識別する方法が必要です。そのために、ffmpegを使って元の動画にフレーム番号のアノテーションを付けた作業用コピーを作成できます。

ANNOTATED_VIDEO=TexasFar1952-annotated.mp4ffmpeg \  -i "$RAW_VIDEO" \  -vf "drawtext=fontfile=Arial.ttf: text='%{frame_num}': start_number=1: x=(w-tw)/2: y=h-(2*lh): fontcolor=black: fontsize=20: box=1: boxcolor=white: boxborderw=5" \  -c:a copy \  "$ANNOTATED_VIDEO"

これにより、次のような動画のコピーが作成されます。

フレームカウントのオーバーレイを追加したパブリックドメイン動画

カタログ作成

次に、テープに収録された映像をカタログ化します。動画を確認しながら、個々のシーンや登場人物、そこで何が起きているかを特定していきます。

お好みの動画プレーヤーを開いてください。私はAdobe Premiere Elementsが最適だと思いますが、無料のOpenShotエディタを試すこともできます。技術的にはどの動画プレーヤーでも動作しますが、フレームごとのコマ送りやズーム可能なタイムラインに対応したものを選ぶと時間を節約できます。

次に、スプレッドシートを作成します。私のスプレッドシートから始めることもできます。各フィールドについて以下で説明します。

私のGoogleスプレッドシートのスクリーンショット

私のスプレッドシートと同じ形式で、すべてのメタデータをスプレッドシートに記録してください。

  • tape_id: 動画ファイルのファイル名(拡張子なし)です。
  • tape_shortname: この素材ファイルに由来するファイルを識別するための短縮名です。tape_idと同じでもかまいません。
  • tape_friendly_name: MediaGoblinがこのクリップがどのテープに由来するかを表示する際に使用するフィールドです。テープのファイル名よりもわかりやすい名前がある場合は、ここに入力してください。
  • scene_start_frame: クリップが始まる最初のフレームの番号です。
    • 例として挙げたテキサス農場の映像では、最初の数フレームは空白なので、最初のクリップはフレーム28から始まります。
  • title: このシーンのタイトルです。出力されるファイル名やMediaGoblinのサムネイルで使用されます。
    • render_scenesに特定の区間を無視させたい場合は、タイトルをjunkにしてください。
  • description: (任意)シーンで何が起きているかの説明です。MediaGoblinの動画視聴画面でクリップの下に表示されます。
  • hashtags: description列の後に、ハッシュマークで始まるタグ列を作成できます。ハッシュタグ列にy(または何らかの値)が入っているクリップには、そのタグがMediaGoblinで追加されます。
    • 例:私のスプレッドシートの9行目では、#adam#archieの列にyが入っています。publish_to_mediagoblinがクリップをMediaGoblinに追加する際に、adamarchieのタグがクリップに追加されます。
    • これらの列の目的は、動画内でタグ付けしたい家族やペットがいる場合に、そのハッシュタグの列を追加し、登場するクリップごとにその列にyを入力できるようにすることです。
  • date: クリップが録画された日付です。
    • 次のいずれかの形式で記述できます。
      • YYYY-MM-DD
      • YYYY-MM
      • YYYY
  • other_tags: クリップに付けたい追加のタグがあれば、カンマ区切りで記述してください。

render_scenes(後述)を実行すると、次の命名規則で動画が短いクリップに分割されます。

  • [tape_shortname] - [clip index] - [title].mp4

例:

  • Texas Family - 1952 - 05 - Archie in the Corn Fields.mp4

シーン情報のYAMLファイルを作成する

クリップのカタログ化ができたら、私のスクリプトを使ってCSVをYAMLファイルに変換できます。このYAMLファイルは、他のスクリプトが動画を分割してMediaGoblinにインポートする方法を指示します。

git clone https://github.com/mtlynch/process-home-videos.gitcd process-home-videosmkdir -p ./venvvirtualenv --python python3 ./venv. venv/bin/activatepip install --requirement requirements.txt

次に、設定ファイルを作成する必要があります。process-home-videos内のconfig.example.yamlconfig.yamlにコピーし、ファイル内の指示に従ってクリップ用に編集してください。

cp config.example.yaml config.yaml

次に、クリップのメタデータであるCSVファイルとYAMLファイルのパスを作成します。

MEDIAGOBLIN_METADATA="${HOME}/mediagoblin-meta"mkdir -p "$MEDIAGOBLIN_METADATA"# Path to the CSV you created.SCENES_CSV="${MEDIAGOBLIN_METADATA}/scenes.csv"# Path to output file to create.SCENES_YAML="${MEDIAGOBLIN_METADATA}/scenes.yaml"

私のスプレッドシートの例に沿って進めている場合は、CSVとしてダウンロードできます。

CSV_URL="https://docs.google.com/spreadsheets/d/1kuamVFEYBrOI097IWBQ8sB0q37ZRACYe2o389Ag92zI/export?format=csv&id=1kuamVFEYBrOI097IWBQ8sB0q37ZRACYe2o389Ag92zI&gid=401061703"wget "$CSV_URL" -O "$SCENES_CSV"

次のスクリプトを実行して、CSVをYAMLファイルに変換してください。

app/csv_to_yaml.py \  --config config.yaml \  "$SCENES_CSV" \  > "$SCENES_YAML"

これにより、次のようなYAMLファイルが作成されます。

$ head -n 19 "$SCENES_YAML"- description: 'Abigail and Adam stand outside with Abigail primping Adam''s coat.    Adam is 12.    Recorded between June 1, 1952 and June 30, 1952.    Came from tape "Texas Farm Family - 1952," scene #01.'  duration_frames: 457  raw_source_filename: TexasFar1952.mp4  rendered_filename: Texas Family - 1952 - 01 - Abigail Primping Adam.mp4  tags:  - abigail  - adam  - best of  timecode_start: '0:00:00.934267'  title: Abigail Primping Adam
これは私のちょっと間抜けな設計判断でした。他のスクリプトはCSVを直接読み込むこともできたのですが、こういう形にしました。

クリップの切り出し

すべてのメタデータの準備ができたので、大きな動画ファイルを一連の小さなクリップに切り出す段階です。

# Specify the directory where the script should write out the processed clips.PROCESSED_CLIPS_DIR="${HOME}/videos-processed"mkdir -p "$RAW_VIDEOS_DIR"app/render_scenes.py \  --metadata "$SCENES_YAML" \  --raw_videos_dir "$RAW_VIDEOS_DIR" \  --output_clips_dir "$PROCESSED_CLIPS_DIR"

スクリプトが完了すると、次のようなフォルダができあがります。

$ ls "$PROCESSED_CLIPS_DIR"'Texas Family - 1952 - 01 - Abigail Primping Adam.mp4''Texas Family - 1952 - 02 - Abigail Standing on the Stairs.mp4''Texas Family - 1952 - 03 - Adam Plays with Cars on the Sidewalk.mp4''Texas Family - 1952 - 04 - Trudy Working at the Loom.mp4''Texas Family - 1952 - 05 - Archie in the Corn Fields.mp4''Texas Family - 1952 - 06 - Tending to the Cows, Bessie Nursing.mp4''Texas Family - 1952 - 07 - Giving Pigs Belly-Rubs.mp4''Texas Family - 1952 - 08 - Checking on the Chickens and Hens.mp4'

MediaGoblin用のファイルを作成する

クリップの処理が終われば、MediaGoblinにファイルをアップロードする準備が整いました。まず、ローカルマシン上のMediaGoblinインスタンスに動画とメタデータをインポートします。これにより、MediaGoblinがファイルを内部データベースとファイル構造に変換し、クラウドでMediaGoblinインスタンスを実行する際に再利用できるようになります。

まず、MediaGoblinの設定ファイルであるmediagoblin.iniに環境情報を入力します。

注意: ホストマシン上のパスとMediaGoblinのDockerコンテナ内のパスを区別しやすくするため、MG_という接頭辞はホストマシン、MGC_はDockerコンテナ内のパスを指すという命名規則に従っています。
MG_CONFIG=$(mktemp)wget https://mtlynch.io/digitizing-home-videos-walkthrough/mediagoblin.ini \  -O "$MG_CONFIG"# Path to MediaGoblin's home directory within the container.MGC_HOME="/var/lib/mediagoblin"MGC_DB_PATH="${MGC_HOME}/mediagoblin.db"# Update the relevant lines in the config file.sed \  --in-place \  "s@.*sql_engine = .*@sql_engine = sqlite:///${MGC_DB_PATH}@" \  "$MG_CONFIG"

次に、コンテナを起動します。

# This is a path on the host machine that will receive the files the MediaGoblin# container generates.MG_SERVING_DIR=$(mktemp --directory)# These are paths within the MediaGoblin container.MGC_INPUT_VOLUME="/opt/input-videos"MGC_APP_DIR="/srv/mediagoblin.example.org/mediagoblin"# Name for MediaGoblin Docker container.MGC_NAME=mediaglindocker run \  --tty \  --detach \  --publish 6543:6543 \  --volume "${PROCESSED_CLIPS_DIR}:${MGC_INPUT_VOLUME}" \  --volume "${MG_CONFIG}:${MGC_APP_DIR}/mediagoblin_host.ini" \  --volume "${MG_SERVING_DIR}:${MGC_HOME}" \  --name "$MGC_NAME" \  mtlynch/mediagoblin

上記のコマンドは、ホストマシン上のいくつかのパスをMediaGoblinコンテナにマウントし、ホストとMediaGoblin間でファイルを共有できるようにします。

  • PROCESSED_CLIPS_DIRにより、MediaGoblinは上記で作成したクリップを読み取ることができます。
  • MG_CONFIGはMediaGoblinが使用する設定ファイルを指定します。
  • MG_SERVING_DIRは、MediaGoblinがローカルファイルシステム上に配置した動画ファイルやサムネイルファイルを受け取ります。

コンテナを実行すると、MediaGoblinの起動に数秒かかります。次のコマンドで進行状況を確認できます。

docker logs "$MGC_NAME" -f

サーバーの準備ができると、次のような行が表示されます。

Starting server in PID 26.Serving on http://0.0.0.0:6543

http://localhost:6543にアクセスして、MediaGoblinサーバーが起動していることを確認できます。

注意: 必要であれば、ユーザー名admin、パスワードadminでログインできますが、ログインは必須ではありません。

次のスクリプトを実行して、クリップとメタデータをMediaGoblinにインポートしてください。

MEDIAGOBLIN_PUBLISH_HISTORY=$(mktemp)app/publish_to_mediagoblin.py \  "$MGC_INPUT_VOLUME" \  --metadata "$SCENES_YAML" \  --publish_history "$MEDIAGOBLIN_PUBLISH_HISTORY" \  --container_name "$MGC_NAME"

スクリプトが完了すると、http://localhost:6543のMediaGoblinのウェブインターフェースにすべてのクリップが表示されるはずです。

MediaGoblinにすべてのクリップが表示された状態

MediaGoblinのウェブインターフェースに、8つのクリップすべてのサムネイルが表示されるはずです。

動画をクリックしても、MediaGoblinが現代のストリーミング最適化された動画形式には古すぎるウェブプレーヤーを使用しているため、通常の動画プレーヤーでは視聴できません。「Original file」リンクをクリックすれば視聴できます。

単一動画ビューのスクリーンショット

ローカルのMediaGoblinインスタンスにおける単一動画の表示

心配はいりません。次のステップで修正するので、すべての動画を埋め込みプレーヤーで通常通り視聴できるようになります。

ローカルコンテナでの作業はこれで完了なので、削除します。

docker rm --force "$MGC_NAME"

Dockerが共有フォルダの所有権を取得したので、取り戻します。

sudo chown "${USER}:${USER}" "$MG_SERVING_DIR" --recursive

そのディレクトリを確認すると、次のような内容が表示されるはずです。

find "$MG_SERVING_DIR" -type f/tmp/tmp.bq7GAbNNNW/media/public/media_entries/8/Texas_Family_-_1952_-_08_-_Checking_on_the_Chickens_and_Hens.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/8/Texas_Family_-_1952_-_08_-_Checking_on_the_Chickens_and_Hens.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/5/Texas_Family_-_1952_-_05_-_Archie_in_the_Corn_Fields.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/5/Texas_Family_-_1952_-_05_-_Archie_in_the_Corn_Fields.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/1/Texas_Family_-_1952_-_01_-_Abigail_Primping_Adam.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/1/Texas_Family_-_1952_-_01_-_Abigail_Primping_Adam.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/4/Texas_Family_-_1952_-_04_-_Trudy_Working_at_the_Loom.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/4/Texas_Family_-_1952_-_04_-_Trudy_Working_at_the_Loom.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/7/Texas_Family_-_1952_-_07_-_Giving_Pigs_Belly-Rubs.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/7/Texas_Family_-_1952_-_07_-_Giving_Pigs_Belly-Rubs.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/6/Texas_Family_-_1952_-_06_-_Tending_to_the_Cows_Bessie_Nursing.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/6/Texas_Family_-_1952_-_06_-_Tending_to_the_Cows_Bessie_Nursing.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/3/Texas_Family_-_1952_-_03_-_Adam_Plays_with_Cars_on_the_Sidewalk.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/media/public/media_entries/3/Texas_Family_-_1952_-_03_-_Adam_Plays_with_Cars_on_the_Sidewalk.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/2/Texas_Family_-_1952_-_02_-_Abigail_Standing_on_the_Stairs.mp4/tmp/tmp.bq7GAbNNNW/media/public/media_entries/2/Texas_Family_-_1952_-_02_-_Abigail_Standing_on_the_Stairs.thumbnail.jpg/tmp/tmp.bq7GAbNNNW/mediagoblin.db/tmp/tmp.bq7GAbNNNW/.cache/gstreamer-1.0/registry.x86_64.bin

Google Cloud Storageの設定

前ステップの目的は、MediaGoblinにすべてのクリップのデータベース、ファイル構成、動画サムネイルを生成させることでした。次はMediaGoblinをクラウドサーバーにデプロイして、ローカルマシンだけでなくどこからでもアクセスできるようにします。

新しいGoogle Cloud Platformプロジェクトを作成する(任意)

MediaGoblin用のファイルを置くためにクリーンなGoogle Cloud Platformプロジェクトを用意したい場合は、以下のコマンドで作成できます。既存のプロジェクトを使用したい場合は、GCP_PROJECT_IDを使用したいプロジェクトIDに設定し、このセクションをスキップしてください。

GCP_PROJECT_NAME="mediagoblin"RANDOM_SUFFIX=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 16 ; echo '')GCP_PROJECT_ID="${GCP_PROJECT_NAME}-${RANDOM_SUFFIX}"gcloud projects create \  "$GCP_PROJECT_ID" \  --name "$GCP_PROJECT_NAME" \  --set-as-default

新しいプロジェクトを請求先アカウントにリンクする必要があります。請求先アカウントの一覧を表示するには、次を実行してください。

gcloud beta billing accounts list

次に、BILLING_ACCOUNTをこのストレージバケットの請求に使用したいアカウントに置き換えてください。

BILLING_ACCOUNT="0X0X0X-0X0X0X-0X0X0X" # Replace with account from the listgcloud beta billing projects link \  "$GCP_PROJECT_ID" \  --billing-account "$BILLING_ACCOUNT"

ストレージバケットを作成する

次に、ファイル用のGoogle Cloud Storageバケットを作成します。私はすべてのオブジェクトを公開するバケットを作成しましたが、ランダムなバケット名を推測することの困難さに依存しています。

24文字のランダムなサフィックスにより、3624 = 2.24 x 1037通りの可能性があります。言い換えれば、攻撃者があなたのバケットを見つけるには約1037個のバケット名を推測する必要があります。これは128ビットの秘密鍵を推測するのと同程度です。
RANDOM_SUFFIX=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 24 ; echo '')BUCKET_NAME="mediagoblin-${RANDOM_SUFFIX}"# All the videos need to be public for users to access them directly from the# browser, but we're adding enough entropy to the bucket name to make it# infeasible for unauthorized users to access the files by guessing or# enumerating URLs.UNIFORM_ACCESS="on"# Bucket storage properties. You can adjust these depending on your preferences.STORAGE_CLASS="Standard"BUCKET_LOCATION="US-EAST1"# Create the GCS bucket.gsutil mb \  -p "$GCP_PROJECT_ID" \  -c "$STORAGE_CLASS" \  -l "$BUCKET_LOCATION" \  -b "$UNIFORM_ACCESS" \  "gs://${BUCKET_NAME}/"# Set uniform access policy for the bucket.# We use legacyObjectReader because it grants read access to individual files but# prevents clients from exploring the bucket's contents.gsutil iam ch allUsers:roles/storage.legacyObjectReader "gs://${BUCKET_NAME}"

ファイルをGoogle Cloud Storageにコピーする

MediaGoblinコンテナがMG_SERVING_DIRディレクトリに生成したファイル(こちら)を覚えていますか?それらを先ほど作成したGoogle Cloud Storageバケットに移動します。

gsutil -m cp -r "${MG_SERVING_DIR}/media/public/*" "gs://${BUCKET_NAME}/"RANDOM_FOLDER=$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 16 ; echo '')gsutil cp "${MG_SERVING_DIR}/mediagoblin.db" "gs://${BUCKET_NAME}/${RANDOM_FOLDER}/"# Save the public URL of the mediagoblin.db file.MEDIAGOBLIN_DB_URL="https://storage.googleapis.com/${BUCKET_NAME}/${RANDOM_FOLDER}/mediagoblin.db"
注意: mediagoblin.dbの保存場所にさらにランダム性を加えているのは、そうしないとバケット名を知っている誰もがデータベースファイルを発見できてしまうためです。このようにエントロピーを追加することで、個々の動画を共有する際にコレクション全体を公開することなく共有できるようになります。

Herokuへのデプロイ

メディアファイルがGoogle Cloud Storage上のインターネットからアクセス可能な場所に置かれたので、あとはMediaGoblinサーバーをデプロイするだけです。HerokuはDockerコンテナに対して寛大な無料枠を提供しており、セットアップも簡単なので利用しています。

このマシンでまだHeroku CLIの認証を行っていない場合は、Herokuの認証情報でログインしてください。

heroku login --interactive

次に、Herokuのコンテナレジストリに認証し、新しいHerokuアプリを作成します。デフォルトでは、作成されるアプリは無料のHeroku dynoになります。

heroku container:loginRANDOM_SUFFIX=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 10 ; echo '')HEROKU_APP_NAME="mediagoblin-${RANDOM_SUFFIX}"heroku apps:create "$HEROKU_APP_NAME"

最後のステップでは、認証設定とタイトルでDockerビルドをカスタマイズし、Herokuにプッシュして公開します。

pushd $(mktemp -d)REPO="https://github.com/mtlynch/mediagoblin-docker.git"# This is a special branch I created that adds authentication and adds a few# other features.TARGET_BRANCH="mtlynch-custom"git clone --single-branch --branch "$TARGET_BRANCH" "$REPO" .HTTP_AUTH_USER="mediagoblin" # change this to a username you chooseHTTP_AUTH_PASS="goblinmedia" # change this to a password you choose# Title you want for your MediaGoblin server.HTML_TITLE="My Demo MediaGoblin Server"heroku container:push web \    --app "$HEROKU_APP_NAME" \    --arg "HTTP_AUTH_USER=${HTTP_AUTH_USER},HTTP_AUTH_PASS=${HTTP_AUTH_PASS},GCS_BUCKET=${BUCKET_NAME},MEDIAGOBLIN_DB_URL=${MEDIAGOBLIN_DB_URL},HTML_TITLE=${HTML_TITLE}"heroku container:release --app "$HEROKU_APP_NAME" web && \  printf "Your app is live at https://${HEROKU_APP_NAME}.herokuapp.com/\n"

すべてがうまくいけば、新しいMediaGoblinインスタンスのURLが次のように表示されます。

Your app is live at https://mediagoblin-v5lmqis51k.herokuapp.com/
注意: Herokuの無料枠を使用しているため、HerokuはブラウザでリクエストがあったときにオンデマンドでMediaGoblinインスタンスを起動します。そのため、最初のページ読み込みには30〜60秒かかり、HTTP 502 Gateway timeoutエラーが表示される場合があります。これは正常な動作です。アプリが起動した後は、数時間アイドル状態にしない限り、高速で応答します。

おまけ:個々の動画を共有する

この手順を家族の動画の保存に使っている場合、家族にはすべての動画を閲覧・アクセスできるようにしたい一方で、コレクション全体へのアクセスを与えることなく個々の動画を他の人と共有したい場合もあるでしょう。

そのようにしたい場合は、MediaGoblinインターフェースの「Original file」リンクをクリックしてください。

「Original file」リンクを指し示すスクリーンショット

これによりゲストはその個別のファイルにアクセスできるようになりますが、Google Cloud Storageバケットの権限を設定した方法により、ライブラリを探索して他の動画にアクセスすることはできません。

「original file」リンクは、次のようなURLになります。

  • https://storage.googleapis.com/mediagoblin-39dpduhfz1wstbprmyk5ak29/media_entries/4/Texas_Family_-_1952_-_04_-_Trudy_Working_at_the_Loom.mp4

ご覧のとおり、上記のURLがあればその単一の動画を視聴できますが、バケットを探索して他の動画を見つけることはできません。


ソースコード

リポジトリ説明
MediaGoblinMediaGoblinコアリポジトリとCircleCI設定のミラーです。

ブランチmtlynch-customには、私のインスタンス用のカスタム修正が含まれています(古い動画プレーヤーを置き換え、不要なUIの一部を削除しています)。
mediagoblin-dockerMediaGoblin用のDockerイメージをビルドします。

ブランチmtlynch-customは、Google Cloud Storageバケットへの紐付けやHTTP Basic認証の追加を含む私のカスタマイズでビルドされます。
process-home-videos生の動画ファイルをクリップに分割し、それらのクリップをMediaGoblinに公開するためのPythonスクリプトです。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント