Sora2のAPIを使用して動画のサムネイルを取得する方法
Sora2のVideo APIは、完成した動画ごとにvariant=thumbnailを指定するとWebP形式のサムネイルを取得できます。
using System.Net.Http;
using System.Net.Http.Headers;
// videoId は生成結果のID(例: "video_abc123")
async Task DownloadThumbnailAsync(string apiKey, string videoId, string outPath = "thumbnail.webp")
{
using var http = new HttpClient();
var url = $"https://api.openai.com/v1/videos/{videoId}/content?variant=thumbnail";
var req = new HttpRequestMessage(HttpMethod.Get, url);
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
using var res = await http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
res.EnsureSuccessStatusCode();
await using var fs = File.Create(outPath);
await res.Content.CopyToAsync(fs);
}
画像の形式をPNGにする方法です。
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
async Task ConvertWebpToPngAsync(Stream webpStream, string outPath = "thumbnail.png")
{
webpStream.Position = 0;
using var image = await Image.LoadAsync(webpStream); // WebPを自動判別で読み込み
await image.SaveAsync(outPath, new PngEncoder());
}
FFmpegをプロセスを作って呼び出しフレームからサムネイルを生成する方法です。
using System.Diagnostics;
async Task<byte[]> ExtractThumbWithFfmpegAsync(Stream videoStream, string ffmpegPath = "ffmpeg")
{
// 1) ストリームを一時MP4へ
string mp4 = Path.Combine(Path.GetTempPath(), $"sora_{Guid.NewGuid()}.mp4");
await using (var fs = File.Create(mp4))
await videoStream.CopyToAsync(fs);
// 2) FFmpegで1フレーム抽出(先頭付近の代表フレーム)
string jpg = Path.Combine(Path.GetTempPath(), $"thumb_{Guid.NewGuid()}.jpg");
var psi = new ProcessStartInfo
{
FileName = ffmpegPath,
// 先頭1秒位置を狙う。画角を軽く縮小(幅640)して圧縮ノイズを抑える例
Arguments = $"-hide_banner -loglevel error -y -ss 00:00:01 -i \"{mp4}\" -vf \"thumbnail,scale=640:-1\" -frames:v 1 \"{jpg}\"",
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var proc = Process.Start(psi)!;
proc.WaitForExit();
// 3) バイト配列で返す(必要ならファイル保存でもOK)
var bytes = await File.ReadAllBytesAsync(jpg);
// 4) 掃除
try { File.Delete(mp4); File.Delete(jpg); } catch { /* ignore */ }
return bytes;
}
以下、注意点。
・ストリーム直パイプ(stdin経由)でも可能ですが、Windows/権限周りで詰まりやすいのでまずは一時ファイル経由を推奨。
・クロスプラットフォームでGUI不要。-ss の時刻や -vf(thumbnail,scale=...)は好みに合わせて調整。
ライブラリで包みたい場合は Xabe.FFmpeg / FFmpeg.AutoGen / OpenCvSharp なども選択肢ですが、まずは生FFmpegが一番簡単。