Communitygithub.com

bigzaqui/videolabs

videolabs サイト全体を公開します(https://videolabs.pages.dev):リポジトリの labs/ フォルダ内のすべてのラボをサイトに同期し(動画は変更時のみ Cloudflare R2 にアップロード、プレイヤーアセット、ラボリソース、カタログ)、videolabs リポジトリをコミット・プッシュして GitHub Actions で Cloudflare Pages にデプロイし、すべてのラボを検証します。ユーザーが videolabs.pages.dev に動画ラボを公開、デプロイ、追加、更新、再アップロードしたい場合に使用します。1回の実行ですべてのラボを公開します(1つだけではありません)。

videolabs とは?

このスキルは、GitHub リポジトリ bigzaqui/videolabs 内の labs/ フォルダにあるすべてのラボを、https://videolabs.pages.dev に公開する完全自動パイプラインを提供します。各ラボの MP4 動画は Cloudflare R2 に変更時のみアップロードされ、プレイヤーアセット、チャプターJSON、ラボリソース、カタログ(site/labs.json)が同期されます。そしてリポジトリが GitHub Actions によって Cloudflare Pages にデプロイされ、全ラボのページが正しく表示され、動画ゲートが有効であることを検証します。一度の実行で全ラボがまとめて公開されるため、ラボの追加・更新・再アップロードが容易に行えます。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bigzaqui/videolabs/tree/HEAD/skills/videolabs_publish

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

videolabs サイトの公開

「公開」とは、すべてのラボを含むサイト全体が毎回デプロイされることを意味します。

サイトリポジトリ: /opt/opus/videolabs (github.com/bigzaqui/videolabs、main ブランチへのプッシュで https://videolabs.pages.dev にデプロイ。GitHub Actions が site/ フォルダを公開します)。 ラボ: /opt/opus/videolabs/labs/<slug>/ (同じリポジトリ内、スラッグごとに1フォルダ。スラッグは MP4 ファイル名 out/<slug>.mp4 に対応)。これらは videolabs_create-video スキル (node engine/cli.mjs <slug> ...) で構築されます。 動画はプライベート R2 バケット videolabs 内の <slug>/<slug>.mp4 に保存され、/media/<slug>/<slug>.mp4 を通じて配信されます。このパスは Turnstile セッションで保護されており(セッションなしのリクエストは 401 を返します)。 認証情報: /opt/opus/videolabs/.env (スクリプトから読み込まれます。テンプレートは .env.example)。シークレットを表示、コピー、コミットしてはいけません。GitHub リポジトリは 公開 です(ユーザーはナレーション音声、スクリプト、キャプチャ、ラボ出力について問題なく、破棄されたラボの使い捨てパスワードがそこに表示されても構いません)。そのため、いかなるファイルにも 実際の 認証情報が含まれてはいけません。このスキルのソースはリポジトリ内の skills/videolabs_publish/ にあり、scripts/setup.sh によって ~/.claude/skills にリンクされています。

ラボに必要なもの(スクリプトでチェック)

  • out/<slug>.mp4 (fast-start 形式: moov が mdat より前にあること。修正するには ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4 を実行)、out/player/chapters.json (node engine/cli.mjs <slug> player で生成)、out/spot.jpg (ポスター画像。ffmpeg -ss 425 -i out/<slug>.mp4 -frames:v 1 -q:v 3 out/spot.jpg でダイアグラムのフレームを取得)。
  • オプション: out/player/lab.json (ラボに lab/lab-meta.json、lab/*.sh、lab/captures/ がある場合、node engine/cli.mjs <slug> player で生成)。これがある場合、site/lab.js がラボページにラボリソースを表示します。キャプチャや lab-meta.json が変更された場合は、最初に node engine/cli.mjs <slug> player を再実行してください。
  • labs/<slug>/lab.config.json には title、description、tags が必要です。スクリプトはこのファイルから site/labs.json のエントリを追加または更新し(minutes と lessons も自動入力されるため)、カタログを手動で編集しないでください。新しいラボの場合、タイトル/説明/タグはラボのスクリプトから明らかであればそれを使用し、そうでなければユーザーに確認してください。黙ってでっち上げないでください。

手順

  1. 計画. cd /opt/opus/videolabs && scripts/publish-all.sh --dry-run を実行します。各ラボに対して1行の PLAN(アップロードまたはスキップの内容、lab.json があるかどうか)、公開できないラボに関する ATTENTION 行(ファイルがない、fast-start でない、lab.config.json がないなど)、プロジェクトがないカタログエントリに関する NOTE 行が出力されます。終了コード2は ATTENTION が1つ以上あることを意味します。それぞれ修正し(lab.config.json を作成、node engine/cli.mjs <slug> player を実行、ポスターを作成するなど)、ATTENTION がなくなるまで繰り返すか、どのラボを除外するかとその理由をユーザーに伝えます。計画を数行でユーザーに表示し、どの動画がアップロードされるかとそのサイズを含めます。
    • アップロード記録がないラボ (state/<slug>.sha256 がない) はアップロードされます。ユーザーが R2 にすでに同じファイルがあると言った場合は、--adopt <slug> を使用してハッシュを記録し、アップロードをスキップします。--force-upload はすべてを再アップロードします。ユーザーが動画の差し替えを依頼した場合のみ使用してください(再アップロード後、最大24時間キャッシュされる可能性があります)。
  2. 同期. scripts/publish-all.sh (同じフラグ) を実行します。準備のできた各ラボについて、まずレンダリングを out/<slug>.web.mp4 に圧縮します (scripts/compress-mp4.sh: モノラル AAC 64k + x264 CRF 28、サイズ約65%削減、動画12分あたり約5分、レンダリングが変更されていない間はキャッシュされます。レンダリング自体は変更されません)。次に、その Web コピーが変更されていれば R2 にアップロードし、lab.config.json からカタログエントリを追加/更新し、chapters.json、poster.jpg、lab.json をコピーします(ラボにない場合はサイトフォルダから削除)、新しいラボ用のページ index.html を作成し(共有テンプレートから、タイトルと説明を含む)、動画のハッシュを state/<slug>.sha256 に記録し、site/labs.json の minutes/lessons を更新します。アップロードは何もプッシュされる前に行われるため、動画なしでページが公開されることはありません。再実行しても安全です。
  3. 確認とコミット. 最初に scripts/check-secrets.sh を実行します(.env の値がファイルに出現した場合、API キー、トークン、パスワード変数に値を代入している場合、または秘密鍵が存在する場合に失敗します)。報告された問題を修正してから進めてください。videolabs リポジトリの git status と差分サマリーをユーザーに表示します(新規/変更されたラボ、labs.json、state/、および共有プレイヤーコードの変更。以下参照)。ラボが GitHub の動画リクエスト(video-request ラベルが付いた Issue)に対応する場合は、コミットメッセージの本文に Closes #N を含めて、main へのプッシュで Issue がクローズされるようにします。labs/*/audio/ が変更された場合も含め、すべてをコミットします(メッセージ例: Publish labs: ceph-first-steps (new), kafka-in-a-nutshell (lab page)、セッションの帰属リマインダーからの Co-Authored-By 行を追加)。そして git push origin main を実行します(SSH リモートは設定済み)。ワーキングツリーに今回のリクエストに無関係な共有プレイヤーコードの変更がある場合は、それらを含めるかどうかを確認してください。
  4. デプロイ. GitHub Actions の実行が完了するのを待ちます (curl -s https://api.github.com/repos/bigzaqui/videolabs/actions/runs?per_page=1 で status/conclusion を確認。約20秒間隔で最大約3分間ポーリング)。失敗した場合は報告し、盲目的に再試行しないでください。シークレット欠落エラーの場合は、リポジトリシークレット CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID の確認が必要です。
  5. site/labs.json 内のすべてのラボを検証(新しいラボだけでなく): / が 200 を返しラボを一覧表示すること、/labs/<slug>/ が 200 を返すこと、/labs/<slug>/chapters.json が JSON を返すこと(HTML フォールバックではない: サイトは未知のパスにも 200 を返すため、コンテンツタイプまたは本文を確認)、/labs/<slug>/lab.json がラボがある場合に JSON を返すこと、/media/<slug>/<slug>.mp4 がセッションなしで 401 を返すこと(ゲートが機能している証拠)。再生自体には Turnstile チェック付きのブラウザセッションが必要なため、再生は行われなかったことを伝えます。URL を報告します: https://videolabs.pages.dev/labs/<slug>/。

1つのラボのみを公開する場合(まれ)、scripts/publish-lab.sh <lab-dir> <slug> "<title>" "<description>" を実行し、site/labs.json を手動で更新してから、手順3に進んでください。

共有コード

site/labs/kafka-in-a-nutshell/index.html は新しいラボごとにコピーされるページテンプレートです(タイトル、見出し、説明は実行時に site/labs.json から取得)。site/lab.js はラボに lab.json がある場合にラボリソースをレンダリングします。site/gate.js は Turnstile チェックです。これらを変更すると、次回のプッシュですべてのラボに影響するため、既存のラボで最初に確認してください。既存のラボはそれぞれ独自の index.html コピーを保持しています。テンプレートの変更が既存ラボに反映されるのは、そのコピーも更新された場合のみです。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル