LoginSignup
6
5

More than 5 years have passed since last update.

Azure functions でexeを使う

Posted at

やりたいこと

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 も初めて使ったので、書き方おかしかったりしたらご指摘ください。

参考

Azure Functions で EXEを実行する

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5