Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@kwgch

Azure functions でexeを使う

やりたいこと

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を実行する

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What are the problem?