1. 程式人生 > >Media start error原因分析及解決方法

Media start error原因分析及解決方法

之前在專案的時候,遇到到Media Recorder在快速啟動停止等一系列操作的後,再次啟動時,會failed的問題,類似的Log如下:

ERROR/MediaRecorder(9008): startfailed:-19                                                                     
WARN/dalvikvm(9008): threadid=15: thread exiting with uncaught exception (group=0x40ad01f8)                             
ERROR/AndroidRuntime(9008): FATAL EXCEPTION: Thread-337                                                                 
ERROR/AndroidRuntime(9008): java.lang.RuntimeException: start failed.                                                   
ERROR/AndroidRuntime(9008):     at android.media.MediaRecorder.start(Native Method)                                     
ERROR/AndroidRuntime(9008):     at com.huawei.ca.eivs.camera.AndroidVideo.initMediaRecoder(AndroidVideo.java:429)       
ERROR/AndroidRuntime(9008):     at com.huawei.ca.eivs.camera.AndroidVideo.sendLiveToMdu(AndroidVideo.java:511)          
ERROR/AndroidRuntime(9008):     at com.huawei.ca.eivs.camera.AndroidVideo$ListenInviteThread.run(AndroidVideo.java:241) 
WARN/ActivityManager(210):   Force finishing activity com.huawei.ca.eivs.ui/com.huawei.ca.eivs.camera.AndroidVideo      
ERROR/ActivityManager(210): exception bw.write()java.io.IOException: Transport endpoint is not connected                

這個時候,退出自己的軟體,開啟系統相機,會提示“相機故障,無法連線到相機”,只能重啟機器才能正常使用系相機。

根據反覆測試抓log發現,造成MediaRecorder start失敗的原因是:在程式中反覆啟動停止MediaRecord時,存在在無效的狀態上stop MediaRecorder的情況,而且沒有捕獲此操作引發的異常,沒有對MediaRecorder進行reset、release造成的。

具體的MediaRecorder狀態遷移,請參看SDK。

解決辦法:
解決這個問題的關鍵是保證MediaRecorder能在合適的狀態執行合適的動作。


下面是我的解決方法,希望能給遇到這個問

</pre>題的人一個靈感:</p><p style="padding-top: 0px; padding-bottom: 0px; margin-top: 0px; margin-bottom: 0px; margin-left: 40px; color: rgb(52, 52, 52); font-family: Simsun; line-height: 24px;"><pre name="code" class="java"><span style="font-family: Simsun;">private void releaseMediaRecorder()</span>
    {
        if (mMediaRecorder != null)
        {
            // 內部標識是否正在錄影的變數,如果不需要可以去掉
            if (isRecord)
            {
                try
                {
                    mMediaRecorder.setOnErrorListener(null);
                    mMediaRecorder.setOnInfoListener(null);
                    // 停止
                    mMediaRecorder.stop();
                   
                }
                catch (RuntimeException e)
                {
                    e.printStackTrace();
	   // 如果發生異常,很可能是在不合適的狀態執行了stop操作
                    // 所以等待一會兒
                    try
                    {
                        Thread.sleep(100);
                    }
                    catch (InterruptedException e1)
                    {
                        Log.e(TAG, "sleep for second stop error!!");
                    }
                }
                isRecord = false;
            }
           
            // 再次嘗試停止MediaRecorder
            try
            {
                mMediaRecorder.stop();
            }
            catch (Exception e)
            {
                Log.e(TAG, "stop fail2", e);
            }
           
            // 等待,讓停止徹底執行完畢
            try
            {
                Thread.sleep(100);
            }
            catch (InterruptedException e1)
            {
                Log.e("TAG", "sleep for reset error Error", e1);
            }
           
            // 然後再進行reset、release
            mMediaRecorder.reset();
            mMediaRecorder.release();
           
            mMediaRecorder = null;
        }
    }