如何调用ffmpeg.exe来转换Windows Azure上的音频文件?

我在Windows Azure上运行Web角色以接收AAC音频文件(由base64字符串上传)并将它们存储到blob中。 它现在工作正常。

接下来,我还必须将它们转换为MP3并将MP3存储到blob中。 我决定使用像ffmpeg.exe -i path .aac path .mp3这样的东西。

问题在于:

  1. 如何在Web角色的Web服务中调用外部ffmpeg.exe
  2. 路径是什么?

如果你知道,请帮助我。 先感谢您。

我建议你为webrole使用本地存储资源 ,在那里你可以从blob存储下载AAC文件,并将它们转换为MP3。 然后上传回blob存储。

另请注意,您还可以使用Path.GetTempFileName()来获取AAC / MP3文件的临时文件名,但我不鼓励这样做(即使我之前已经这样做过)。

至于运行的执行ffmpeg,您可能想要浏览我之前构建的AzureVideoConv的代码。 你会在那里找到很多有用的代码。

下面是一个实际ffmpeg调用的示例(请注意,我从blob存储中下载了exe,以避免使用外部exe文件膨胀我的azure包,并在需要时轻松更新ffmpeg.exe):

internal void ConvertFile(string inputFileName, Guid taskID) { string tmpName = string.Format( "{0}\\{1}.flv", Path.GetTempPath(), inputFileName.Substring(inputFileName.LastIndexOf("\\")+1)); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = this._processorExecutable; psi.Arguments = string.Format(@"-i ""{0}"" -y ""{1}""", inputFileName, tmpName); psi.CreateNoWindow = true; psi.ErrorDialog = false; psi.UseShellExecute = false; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.RedirectStandardOutput = true; psi.RedirectStandardInput = false; psi.RedirectStandardError = true; try { // Start the process with the info we specified. // Call WaitForExit and then the using statement will close. using (Process exeProcess = Process.Start(psi)) { exeProcess.PriorityClass = ProcessPriorityClass.High; string outString = string.Empty; // use ansynchronous reading for at least one of the streams // to avoid deadlock exeProcess.OutputDataReceived += (s, e) => { outString += e.Data; }; exeProcess.BeginOutputReadLine(); // now read the StandardError stream to the end // this will cause our main thread to wait for the // stream to close (which is when ffmpeg quits) string errString = exeProcess.StandardError.ReadToEnd(); Trace.WriteLine(outString); Trace.TraceError(errString); byte[] fileBytes = File.ReadAllBytes(tmpName); if (fileBytes.Length > 0) { this._sSystem.SaveOutputFile( fileBytes, tmpName.Substring(tmpName.LastIndexOf("\\")+1), taskID ); } } } catch (Exception e) { Trace.TraceError(e.Message); } } 

注意项目的最后一次检入是使用Windows Azure SDK 1.3

非常感谢@astaykov。 你做得好。 虽然它不是特定于我的情况(我需要一段特定的代码而不是整个大项目),但它确实激励了我。 为了说明我的情况,我将自己回答这个问题 – 请注意, 我是根据@ astaykov的代码在某处直接复制和粘贴的

  1. 首先,使用本地存储资源配置角色。 然后通过这些代码得到它的路径:

      LocalResource converter_path = RoleEnvironment.GetLocalResource("AudioConvertSpace"); string rootPathName = converter_path.RootPath; 
  2. 在本地存储中获取ffmpeg.exexxx.aacxxx.mp3的路径:

      string aac_path = rootPathName + "\\" + "fmwa-" + guidguid + ".aac"; string mp3_path = rootPathName + "\\" + "fmwa-" + guidguid + ".mp3"; string exe_path = rootPathName + "\\" + "ffmpeg.exe"; 
  3. 将.aac文件写入本地存储:

      System.IO.File.WriteAllBytes(aac_path, decoded_audio_byte_array); 
  4. 请记住,本地存储不能保证稳定或持久,因此请检查ffmpeg.exe是否存在 – 如果不存在,请从blob下载。

      if (System.IO.File.Exists(exe_path) == false) { var exeblob = _BlobContainer.GetBlobReference("ffmpeg.exe"); exeblob.DownloadToFile(exe_path, null); } 
  5. 初始化并运行ffmpeg.exe进程:

      ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = exe_path; psi.Arguments = string.Format(@"-i ""{0}"" -y ""{1}""", aac_path, mp3_path); psi.CreateNoWindow = true; psi.ErrorDialog = false; psi.UseShellExecute = false; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.RedirectStandardOutput = true; psi.RedirectStandardInput = false; psi.RedirectStandardError = true; Process exeProcess = Process.Start(psi); exeProcess.PriorityClass = ProcessPriorityClass.High; string outString = string.Empty; exeProcess.OutputDataReceived += (s, e) => { outString += e.Data; }; exeProcess.BeginOutputReadLine(); string errString = exeProcess.StandardError.ReadToEnd(); Trace.WriteLine(outString); Trace.TraceError(errString); exeProcess.WaitForExit(); 
  6. 将ffmpeg.exe的输出上传到blob存储中:

      byte[] mp3_audio_byte_array = System.IO.File.ReadAllBytes(mp3_path); var mp3blob = _BlobContainer.GetBlobReference("fmwa-"+guidguid+".mp3"); mp3blob.Properties.ContentType = "audio/mp3"; mp3blob.UploadByteArray(mp3_audio_byte_array); 
  7. 清理临时文件:

      System.IO.File.Delete(aac_path); System.IO.File.Delete(mp3_path);