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



我在Windows Azure上运行一个Web角色来接收AAC音频文件(通过base64字符串上传)并将它们存储到blob中。到目前为止还可以。

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

问题是:

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

如果你知道请帮助我。

我建议您使用本地存储资源,您可以从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的路径。本地存储中的Aac xxx.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);
    

最新更新