1. 程式人生 > >ffmpeg,記一次錄音文件信息裏面碼率,時間丟失的問題。

ffmpeg,記一次錄音文件信息裏面碼率,時間丟失的問題。

start .exe erro 生成 bps 界面 思考 isp writer

1.起因

  同事在調用錄音控件生成的MP3,在部分瀏覽器中加載失敗,出現彈框提示。

  技術分享

經過同事的對比,發現當文件屬性中比特率 為0kbps,時長為空的時候就會出現上圖這種情況。並給找到一個解決方案,使用ffmpeg進行一次轉碼後就會出現比特率和時長,瀏覽器也可以正常加載。

ffmpeg.exe -i out.mp3 -b:a 128k -y -acodec libmp3lame  out2.mp3  //cmd 中執行轉換命令

異常的情況技術分享 正常的情況技術分享

2.問題原因

  由上面可以知道,mp3文件是由於比特率信息丟失導致的問題出現,通過查找文檔,多次修改參數試驗,問題一直存在。偶然一次再參數裏設置了錄音時間,發現生成的文件時正常的。得出結論,是ffmpeg.exe沒有正常關閉導致,文件信息沒有寫完。

ffmpeg沒有正常關閉的原因,測試時候是用過關閉cmd窗口,用播放器播放mp3文件發現音頻可以正常播放,也就沒有過多思考,在代碼實現過程了,通過直接kill掉Process來實現錄制完畢。

技術分享

        [DllImport("kernel32.dll")]
        static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);

        [DllImport("kernel32.dll")]
        static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool
add); [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll")] static extern bool FreeConsole(); /// <summary> /// 功能: 停止錄制 /// </summary> public static void Stop() {
try { AttachConsole(p.Id); SetConsoleCtrlHandler(IntPtr.Zero, true); GenerateConsoleCtrlEvent(0, 0); FreeConsole(); //p.Close(); if (!p.HasExited) { p.Kill(); p.WaitForExit(); } // p.Dispose(); } catch (Exception ex) { // Log.Error("關閉錄音工具ffmpeg異常", ex); } }

所以只需要正常關閉錄制就可以解決這個問題,後來發現上圖cmd界面中倒數第二行 Press [q] to stop, 試驗了下果然可以,生成的MP3也是正常的。現在只需要代碼模擬輸入q就可以解決這個問題了,

c#代碼如下

  static StreamWriter myStreamWriter;
        /// <summary>
        /// 功能: 開始錄制
        /// </summary>
        public static void Start(string audioDevice, string outFilePath)
        {
            if (File.Exists(outFilePath))
            {
                File.Delete(outFilePath);
            }

            ProcessStartInfo startInfo = new ProcessStartInfo(ffmpegPath);
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.CreateNoWindow = true; //不加這句會顯示cmd窗口
            startInfo.UseShellExecute = false; //關閉Shell的使用
            startInfo.RedirectStandardOutput = true; //重定向標準輸出
            startInfo.RedirectStandardInput = true;
            startInfo.Arguments = audioDevice;

            p = new Process();
            p.StartInfo = startInfo;

            p.Start();
            myStreamWriter = p.StandardInput;
        }

        /// <summary>
        /// 功能: 停止錄制
        /// </summary>
        public static void Stop()
        {
            try
            {
                myStreamWriter.WriteLine("q");

                Thread.Sleep(100);//q命令沒有那麽快執行
                if (!p.HasExited)
                {
                    p.Kill();
                    p.WaitForExit();
                }

                // p.Dispose();
            }
            catch (Exception ex)
            {
               // Log.Error("關閉錄音工具ffmpeg異常", ex);
            }
        }

分享一個錄音的測試demo https://pan.baidu.com/s/1mizerUS

ffmpeg,記一次錄音文件信息裏面碼率,時間丟失的問題。