Expression Encoder 2 SDK で連続エンコード プログラムを作る
こんにちははらだんです。今日は昨晩遅かったために、起きたのが夕方の15:00でした…。この時間におきると本当に1 日損した気分になりますね。そうも言っていられないので洗濯を 1 回まわして京王線は府中駅まで出かけました。漫画と NHK 英会話のテキスト、ミニ四駆を購入してお茶して帰るのが目的です。
漫画で読破というシリーズを見かけ 3 冊ほど買ってみました。名作と呼ばれる文学を漫画化したシリーズなのだそうです。はらだんはこれまで文学はあまり読んでいないので、原作と比べてどれほど駆け足になっているのか不明なのですが…。それから「暴れん坊少納言」(清少納言、この少女、いとツンデレなり。だそうです)を試しに 1 巻だけ買ってみました。
そうそう、ミニ四駆は ILM チームのぴろとさんと時々遊びに行きます。はらだんは子供のころにミニ四駆で遊んでいないので、こういう世界は知りませんでした。本日は新しくタイガース モデルが発売されていたので買ってきました。同時に発売されたアバンテという車とどっちにするか迷いましたが・・。
前振り長かったのですが、
本日のお題:
Expression Encoder 2 SDK を使って指定したフォルダ内のコンテンツを片端からエンコードするコマンドライン エンコーダ プログラム
を作ってみます。簡単です。
Expression Encoder のオブジェクトについては SDK のヘルプ ファイルがいまいちなので、以前の記事も参考にしてみてください。
使用している言語は C# です。コマンドライン引数についてはエンコード元のファイルが保存されているフォルダ、エンコード後のファイルを保存するフォルダ、ビデオのビットレートを指定できるようにしてあります。パーサーはいい加減ですので、ちゃんと使ってみたい方はそれなりの実装とエンコード処理部分でもエラー処理を実装して頂けるとぐっと使いやすくなります。(と言って逃げる)
実行方法はコマンド プロンプトから以下のように指定します。
TestEncoder <ソースフォルダ> <出力フォルダ> [-b <ビットレート>]
プログラムの処理
~~~~~~~~~~
指定されたフォルダ内をサブフォルダも含めて巡回し、ファイルをすべて動画もしくは音声ファイルとみなし MediaItem に放り込みます。エラーが出たらそのファイルは「読めないコーデックのコンテンツ」として処理せずに飛ばします。(テキスト ファイルだとしてもお構いなしに MediaItem に放り込みます)
出力先フォルダは指定してください。すでに同名のファイルが出力フォルダに出来ている場合は上書きされます。
エンコードするコーデックは VC-1 メインプロファイルの CBR です。ソースコードの該当部分を変更すれば他の設定でもエンコードできます。入力は AVI,WMV,MPEG,WMA,WAV 等が使え(コーデックにもよります。)出力は動画は WMV に、音声は WMA になります。
エンコード設定のパラメータについて設定範囲等 SDK の HELP には書かれていない部分を以下に補足します。(本当に申し訳ない HELP ドキュメントです。)
エンコードパラメータ
~~~~~~~~~~~~
VideoProfile.BufferWindow
ファイルの再生前にバッファに保存される秒数
ms (ミリ秒)で設定します。範囲は 100 (0.1秒) ~ 100000 (100秒)です。
VideoProfile.Bitrate
ビットレートの指定
4Kbps ~ 20Mbps (K(キロ)=1024 計算)の間で指定します。
AudioProfile.Bitrate
ビットレートの指定
4kbps ~ 20Mbps ですが、コーデックの種類と SampleRate に依存したとびとびの値しか指定できません。例えば、5Kbps - 8kHz など。とびとびの値は 5 ,6 ,8, 10, 12, 16, 20, 22, 24, 32, 40, 48, 64, 80, 96, 128, 160, 192 (Kbps)ですが、 K(キロ) = 1000 計算です。具体的には 128Kbps は 128*1000 です。128*1024 ではありません。
-
using System;
using System.IO;
using Microsoft.Expression.Encoder;
using Microsoft.Expression.Encoder.Profiles;
namespace TestEncoder2
{
class Program
{
public static string SrcFolder, DstFolder;
public static int BitRate=1024*1024; //1Mbps
public static void DoEncode(string SrcFile)
{
Job MyJob;
VideoProfile MyVideoProfile;
MediaItem MyMediaItem;
MyJob = new Job();
try
{
MyMediaItem = new MediaItem(SrcFile);
}
catch
{ //コーデック知らないという場合など
Console.WriteLine("Error:"+SrcFile);
return;
}
MyJob.MediaItems.Add(MyMediaItem);
MyVideoProfile = new VideoProfile();
MyJob.OutputDirectory = DstFolder; //出力フォルダ設定
MyJob.CreateSubfolder = false; //サブフォルダは作成しない
//エンコード設定
MyVideoProfile.FrameRate = 29.97;
MyVideoProfile.KeyFrameSpacing = 5;
MyVideoProfile.CodecProfile = VideoCodecProfile.Main;
MyVideoProfile.Mode = VideoMode.Cbr;
MyVideoProfile.BufferWindow = 5000;
MyVideoProfile.Width = MyMediaItem.VideoProfile.Width; // Src の Size
MyVideoProfile.Height = MyMediaItem.VideoProfile.Height; // Src の Size
MyVideoProfile.Bitrate = 1024*1024;
MyMediaItem.VideoProfile = MyVideoProfile;
MyMediaItem.AudioProfile.Bitrate = 128*1000;
MyMediaItem.AudioProfile.SampleRate = 44100;
//エンコードします
Console.WriteLine(SrcFile);
MyJob.Encode();
}
public static void DirList(string RootDir)
{
//フォルダ内のすべてのファイル
foreach (string file in Directory.GetFiles(RootDir))
{
//Do Encode
DoEncode(file);
}
//サブフォルダ
foreach (string folder in Directory.GetDirectories(RootDir))
{
Console.WriteLine(folder);
DirList(folder);
}
}
static void Main(string[] args)
{
//☆☆☆ コマンドライン引数のパーサは省略! ☆☆☆
if (args.Length > 0)
{
int index;
SrcFolder = args[0];
if (args.Length > 1)
{
index = 1;
while (index < args.Length)
{
if (args[index].Equals("-b") || args[index].Equals("-B"))
{
BitRate = int.Parse(args[index + 1])*1024;
//Kbpsで入力するのでbpsに変換
if (BitRate < 4096) BitRate = 4096;
if (BitRate > 20 * 1024 * 1024) BitRate = 20 * 1024 * 1024;
index += 2;
}
else
{
//出力フォルダとみなす
DstFolder = args[index];
index++;
}
}
}
//フォルダ内のファイルを探索し順次エンコード処理を実行する
DirList(SrcFolder);
}
}
}
}
次回はライブ エンコード モードを試したいですね。