Azure Functions で音楽ファイルを変換
Azure で音楽ファイルを変換するために Azure Functions と ffmpeg を使ってみました。本記事はその備忘録です。
プロジェクトの構成
今回は Visual Studio Code で Function を開発&デプロイするものとします。 Function を生成し、プロジェクトのルートディレクトリに ffmpeg.exe を配置します。
実装
デプロイ時に ffmpeg のバイナリも一緒に配置したいので、csproj ファイルに以下を追記します。
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup>
...
<None Update="ffmpeg.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
C#スクリプトのうち、ffmpeg を使って変換するメソッドは次のように書きました。 普通に Process.Start しているだけです。 変換のついでに90秒後にフェードアウトするよう指定しています。
private static string basePath = "D:\\home\\site\\wwwroot\\";
private static void Convert(string srcPath, string dstPath)
{
var startInfo = new ProcessStartInfo()
{
FileName = basePath + "ffmpeg.exe",
Arguments = $"-i \"{ srcPath }\" -ar 44100 -ab 192k "
+ "-t 90 " // 90秒にカット
+ "-af \"afade=t=out:st=89:d=1\" " // 最後の1秒はフェードアウト
+ "-vn -map_metadata -1 " // メタデータを削除
+ "-c:v copy " // ビデオはコピー(バグ回避)
+ $"\"{ dstPath }\" -y", // 上書き
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(startInfo);
process.WaitForExit((int)TimeSpan.FromSeconds(60).TotalMilliseconds);
}
OSコマンドインジェクションの脆弱性がありそう。
Runメソッドを含む完全な C# スクリプトの実装は gist に置きました。 これは以下のような Function になっています。
- Function は HTTP Trigger
- 音楽ファイルのリソース(URL)を POST すると、変換後の音楽ファイルのリソース(URL)が返される
- 変換後の音楽ファイルは Azure Blob Storage に配置する
- 任意の音楽形式から m4a に変換
まとめ
Azure Functions と ffmpeg を使って音楽ファイルを変換する方法を紹介しました。
最初は Azure Media Services の Media Encorder 機能でサクッと音楽ファイルを変換できることを期待したのですが、この機能はいまのところ動画形式しか出力できないようです。 入力には m4a や flac などの音楽形式を与えることはできるのですが… Amazon Elastic Transcoder のように音楽形式の変換にも対応してくれると嬉しいところです。