Skip to content

Instantly share code, notes, and snippets.

@4423
Created May 21, 2019 06:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 4423/516e5a344ae4721467c75130a4299424 to your computer and use it in GitHub Desktop.
Save 4423/516e5a344ae4721467c75130a4299424 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;
using System.Net;
namespace Company.Function
{
public static class M4AConverter
{
private static string basePath = @"D:\home\site\wwwroot\";
[FunctionName("M4AConverter")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log)
{
// "{ "url": "https://hoge.com/ongen.flac" }" のような JSON から url を取得
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
Uri srcurl = new Uri((string)data?.url);
// originalPath: D:\home\site\wwwroot\ongen.flac
// outputPath: D:\home\site\wwwroot\ongen.flac.m4a
string originalPath = basePath + Path.GetFileName(srcurl.LocalPath);
string outputPath = originalPath + ".m4a";
try
{
// ダウンロード
using (var client = new WebClient())
{
client.DownloadFile(srcurl, originalPath);
}
// ffmpeg で変換
Convert(originalPath, outputPath, log);
// 変換後のファイルを Blob にアップロード
var account = ConnectBlob();
var blobUri = await UploadBlob(account, outputPath);
// アップロードした場所を返す
return (ActionResult)new OkObjectResult(blobUri);
}
catch (Exception ex)
{
return new BadRequestObjectResult(ex.Message);
}
finally
{
void DeleteIfExists(string path)
{
if (File.Exists(path)) File.Delete(path);
};
DeleteIfExists(originalPath);
DeleteIfExists(outputPath);
}
}
private static CloudStorageAccount ConnectBlob()
{
string getenv(string name) =>
Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
string accountName = getenv("BlobAccountName");
string accessKey = getenv("BlobAccessKey");
var credential = new StorageCredentials(accountName, accessKey);
return new CloudStorageAccount(credential, true);
}
private static async Task<string> UploadBlob(CloudStorageAccount storageAccount, string path)
{
var blockBlob = storageAccount.CreateCloudBlobClient()
.GetContainerReference("tmp")
.GetBlockBlobReference($"{DateTime.Now.Ticks}.m4a");
await blockBlob.UploadFromFileAsync(path);
return blockBlob.Uri.AbsoluteUri;
}
private static void Convert(string srcPath, string dstPath, ILogger log)
{
var startInfo = new ProcessStartInfo()
{
FileName = "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);
log.LogInformation(process.StandardOutput.ReadToEnd());
log.LogInformation(process.StandardError.ReadToEnd());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment