⭐️

.NET8とAzure AI FoundryのSora 2で生成した動画をYouTubeに自動でアップロードするプログラムを作成してみた

に公開

この記事で伝えたいこと(ポイント)

  • Azure AI FoundryのSoraを使って動画生成を試してみたよ
  • Soraで生成した動画をYouTubeに自動でアップロードするプログラムを作成してみたよ

はじめに

この記事はSoraで生成した動画をYouTubeに自動でアップロードするプログラムを作成してみた内容について書いています。

主な内容としてはセットアップや使い方を中心に書きます。(忘れやすいことなど)
誤りなどがあれば修正していく想定です。

このプログラムはGitHubで公開しています。

注意事項

この記事ではいくつかのAPIキーやOAuth 2.0クライアントIDなどの機密情報を扱います。
これらの情報は第三者に知られないように注意してください。

また、YouTube Data APIの利用にはGoogleの利用規約に従う必要があります。
不適切なコンテンツのアップロードやスパム行為は禁止されています。

Azure AI FoundryのSoraで動画生成を試す方法について

生成方法の詳細については以下の記事を参照してください。

やること

  • Azure AI FoundryのSora で動画を生成する
  • YouTube APIのセットアップを行う
  • OAuth 2.0で認証をセットする
    • client_secrets.jsonを使って認証情報を取得する(デスクトップアプリケーションとして認証を行う)
  • az loginで認証を行う
  • YouTube Data APIを使って動画をYouTubeにアップロードする

ハンズオン環境

今回のプログラムはGitHubで公開していますのでとりあえず、動かしてみましょう。

今回のハンズオン環境は以下の通りです。

  • Azure AI Foundryプロジェクト
    • Soraのモデルがsora2という名前でデプロイされていることを前提とします
  • 認証
    • Cognitive Services OpenAI UserあるいはCognitive Services OpenAI Contributorのロールが必要です

プログラム上ではAzureDefaultCredentialを使ってAzure OpenAI(Azure AI Foundry)に接続します。
なお、Azure AI FoundryのAPI利用例を見る限りではまだSDKが提供されていないようなので、REST APIを直接呼び出す形で実装します。

Google APIについてはGoogle.Apis.YouTube.v3パッケージを使ってYouTube Data APIを利用します。
必要なものは以下の通りです。事前に作成しておく必要があります。

  • Google Cloudプロジェクト
  • YouTube Data APIを有効化
  • OAuth 2.0クライアントID(デスクトップアプリケーションとして作成)
  • client_secrets.jsonのダウンロード

Azure CLIのインストールとログイン

Codespacesが起動したら、Azure CLIをインストールします。

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

続いて、Azure CLIでログインします。

az login

ブラウザが起動するので、指示に従ってログインします。

Azure AI Foundryのセットアップ

Azure AI Foundryプロジェクトの概要からAzure AIサービスをクリックします。
Azure AIサービスAzure AI サービスエンドポイント(環境変数ではAZURE_OPENAI_ENDPOINTとなるもの)をコピーして控えておきます。
※AZURE_OPENAI_ENDPOINTはhttps://{your-custom-endpoint}.openai.azure.com/のような形式になっています。

以下の環境変数を設定します。

export AZURE_OPENAI_DEPLOYMENT_NAME=sora2
export AZURE_OPENAI_ENDPOINT=your-endpoint-here
export USE_API_KEY=0

your-endpoint-hereは実際のエンドポイントURLに置き換えてください。
AZURE_OPENAI_DEPLOYMENT_NAMEですが、プログラム上でsora2という名前にしてあります。それ以外のデプロイ名では動作しないので注意してください。
なお、APIキーを使った認証にも対応しています。その場合は上記の環境変数に加えて、USE_API_KEYを1に設定して環境変数AZURE_OPENAI_API_KEYにAPIキーを設定します。

export USE_API_KEY=1
export AZURE_OPENAI_API_KEY=your-api-key-here

コンソールアプリの実行

コンソールアプリを実行します。

dotnet run

実行後、以下のようなメッセージが表示されます。

--- 1. ジョブを作成中 ---
エンドポイント: https://your-endpoint-here/
ジョブが作成されました: task_01k7t3ps0kevstdpy3abhwearb
レスポンスJSON: {
  "object": "video.generation.job",
  "id": "task_01k7t3ps0kevstdpy3abhwearb",
  "status": "preprocessing",
  "created_at": 1760739156,
  "finished_at": null,
  "expires_at": null,
  "generations": [],
  "prompt": "A young woman walks through a rainy street in Tokyo. Shallow depth of field. Neon lights reflect off the wet pavement. Ambient sound: rain and city noise.She stops under a red awning, takes out her phone, and says, dialogue: “I hope he’s still awake.” Close-up. Warm side light from a vending machine.",
  "model": "sora2",
  "n_variants": 1,
  "n_seconds": 5,
  "height": 480,
  "width": 480,
  "inpaint_items": null,
  "failure_reason": null
}

--- 2. ステータスを確認中 (5秒ごとにポーリング) ---
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: queued
ジョブステータス: running
ジョブステータス: processing
ジョブステータス: processing
ジョブステータス: processing
ジョブステータス: processing
ジョブステータス: succeeded
✅ ビデオ生成が成功しました。
ビデオコンテンツをダウンロード中...
生成されたビデオは「output.mp4」として保存されました。

--- 4. YouTubeにアップロード中 ---
アップロードを開始します...
✅ アップロード完了!
ビデオID: video_id_here

出力されたレスポンスにはprompt(プロンプト)が含まれています。
今回は"A young woman walks through a rainy street in Tokyo. Shallow depth of field. Neon lights reflect off the wet pavement. Ambient sound: rain and city noise.She stops under a red awning, takes out her phone, and says, dialogue: “I hope he’s still awake.” Close-up. Warm side light from a vending machine."としています。

実行結果

実行結果は以下の通りです。お手元にoutput.mp4の動画が保存されており、YouTubeにもアップロードされているはずです。
デフォルトでは非公開でアップロードされます。

サンプル動画はこちらです。

https://youtube.com/shorts/G0YdQj7SQuI?feature=share

中身を見る

うまくいったところで中身を見てみましょう。今回はジョブ作成時に以下のようなJSONが返ってきます。

レスポンスJSON

{
  "object": "video.generation.job",
  "id": "task_01k7t3ps0kevstdpy3abhwearb",
  "status": "preprocessing",
  "created_at": 1760739156,
  "finished_at": null,
  "expires_at": null,
  "generations": [],
  "prompt": "A young woman walks through a rainy street in Tokyo. Shallow depth of field. Neon lights reflect off the wet pavement. Ambient sound: rain and city noise.She stops under a red awning, takes out her phone, and says, dialogue: “I hope he’s still awake.” Close-up. Warm side light from a vending machine.",
  "model": "sora2",
  "n_variants": 1,
  "n_seconds": 5,
  "height": 480,
  "width": 480,
  "inpaint_items": null,
  "failure_reason": null
}

このレスポンスで重要なところとしては以下の通りです。

  • prompt: 動画生成に使われたプロンプト
  • model: 利用されたモデル名
  • n_seconds: 生成された動画の長さ(秒)
  • height: 生成された動画の高さ(ピクセル)
  • width: 生成された動画の幅(ピクセル)
  • status: ジョブのステータス

では、コードの中身を見ていきましょう。

prompt

生成に使われたプロンプトです。リクエストに含まれていた内容がそのまま返されます。C#のModelで作成しています。

プログラム上では以下のように設定しています。
https://github.com/ymd65536/SoraMovieUploader/blob/bca85b9df71964c5dc03faf2c6c3665b941ba810/Models/VideoGenerationRequest.cs#L7-L8

model

利用されたモデル名です。今回はsora2を指定しています。プログラム上では以下のように設定しています。

https://github.com/ymd65536/SoraMovieUploader/blob/bca85b9df71964c5dc03faf2c6c3665b941ba810/Models/VideoGenerationRequest.cs#L19-L20

ここだけはデフォルトのモデル名としてsoraを指定しています。

heightとwidth

生成された動画の高さと幅です。プログラム上では以下のように設定しています。

https://github.com/ymd65536/SoraMovieUploader/blob/bca85b9df71964c5dc03faf2c6c3665b941ba810/Models/VideoGenerationRequest.cs#L10-L14

動画の解像度を変更する場合はここを変更します。

n_seconds

生成された動画の長さ(秒)です。プログラム上では以下のように設定しています。

https://github.com/ymd65536/SoraMovieUploader/blob/bca85b9df71964c5dc03faf2c6c3665b941ba810/Models/VideoGenerationRequest.cs#L16-L17

YouTubeにアップロードする動画の長さとoutput.mp4の長さがここで決まります。

気になる点

今回はSora 2で動画を生成していますが、音声が入っていない動画になっています。
音声が入る想定でしたが、今回の検証では音声が入っていませんでした。

また、Sora 2のドキュメントにはSoraとの比較は書いてありますが、Sora2に関するAPIリファレンスがまだ見当たりません。
Video generation with Sora (preview)

なお、Video generation modelsの項目にもSora 2に関する記載はあります。
Foundry Models sold directly by Azure

他にもAzure AI Foundryのビデオグラウンドで提供されているサンプルコードを動かしても音声は入りませんが
プレイグラウンドでは音声付きの動画で生成されます。

プレイグラウンドで提供されるサンプルコードとしてC#のコードがありましたが
トップレベルのステートメントで書かれていない点やNewtonsoft.Jsonを使っている点など少しだけ違和感を感じました。

まとめ

今回はSoraで生成した動画をYouTubeに自動でアップロードするプログラムを作成してみました。
Azure AI Foundryを使うと簡単に動画生成ができ、YouTube APIを使うことで自動でアップロードも可能です。
気になる点が多かったので、今後のアップデートに期待したいと思います。

Discussion