#やりたいこと
Blob Storageに配置されたオブジェクトをexeで処理したい
#前提
- Blob Triggerなど Blogとバインディングされたfunctionを登録
- functionの場所にBinフォルダを用意
- exeをBinフォルダに置いておく
#やりかた
例) ffmpegで動画ファイルから音声だけ抜き出す
function.json
{
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "files/{name}",
"connection": "xxx_STORAGE"
},
{
"type": "blob",
"name": "outputBlob",
"path": "files/{rand-guid}.wav",
"connection": "xxx_STORAGE",
"direction": "out"
}
],
"disabled": false
}
以下、ソース内コメントで解説
run.csx
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Diagnostics;
public static void Run(CloudBlockBlob myBlob, string name, string blobTrigger, Stream outputBlob, TraceWriter log)
{
try {
// フルパス
String basePath = @"D:\home\site\wwwroot\BlobTriggerCSharp\";
String stFilePath = basePath + name;
// ファイルをダウンロード
myBlob.DownloadToFile(stFilePath, System.IO.FileMode.Create);
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
// exeを指定
startInfo.FileName = basePath + @"Bin\ffmpeg.exe";
// 実行時パラメータを指定
startInfo.Arguments = "-i " + stFilePath + " -ac 1 -ar 16000 -acodec pcm_s16le -f wav " + basePath + "sample.wav";
// ウインドウ非表示
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
// 標準エラー出力をリダイレクト
startInfo.RedirectStandardError = true;
// 標準出力をリダイレクト
startInfo.RedirectStandardOutput = true;
// シェル実行ではない
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
// 実行
process.Start();
// 処理完了をまつ
process.WaitForExit();
// 出力したファイルを読み込む
FileStream SourceStream = File.Open(basePath + "sample.wav", FileMode.Open);
// 出力用blobに出力
SourceStream.CopyTo(outputBlob);
// 標準エラー出力をログ出力
StreamReader myStreamReader = process.StandardError;
log.Info( myStreamReader.ReadLine());
// 標準出力をログ出力
StreamReader myStreamReader2 = process.StandardOutput;
log.Info( myStreamReader2.ReadLine());
// 読み取り専用を解除
System.IO.FileInfo cFileInfo = new System.IO.FileInfo(stFilePath);
if ((cFileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly){
cFileInfo.Attributes = FileAttributes.Normal;
}
// 使い終わったファイルを削除
cFileInfo.Delete();
} catch(Exception e) {
log.Info(e.Message);
log.Info(e.StackTrace);
}
}
注意
上記例だと、トリガーを設定している入力用blobと出力用blobが同じなので、ファイルができた瞬間に再度呼ばれてしまう。
エラーになるので無限ループにはならない。
azure functions も C# script も初めて使ったので、書き方おかしかったりしたらご指摘ください。