重启Android MediaRecorder时出现IllegalStateException [以无效状态启动:1]

时间:2014-01-28 03:13:36

标签: java android mediarecorder

我正在尝试使用简单的逻辑来启动/停止使用Android MediaRecorder进行录制。

周期是

  1. 连接到localSocket / set options / mRecorder.prepare();
  2. mRecorder.start();
  3. mRecorder.stop(); mRecorder.reset();
  4. 然后,在2和3之间循环。

    在第一个循环中,1,2,3按预期正常工作,但是,第一次停止后第二次启动(重启)时出现错误。

    com.example.app E/MediaRecorder﹕ start called in an invalid state: 1

    什么是MediaRecorder state 1?我错过了什么? 感谢您的投入。

    if (cmd.equals("connect"))
    {
        try
        {
            sender.connect(new LocalSocketAddress(SOCKET_ADDRESS)); 
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mRecorder.setOutputFile(sender.getFileDescriptor()); 
            mRecorder.prepare(); 
        }
        catch (IOException e)
        {   e.printStackTrace();  } 
    } 
    if (cmd.equals("start"))
    {
        try
        { 
            mRecorder.start(); 
        }
        catch (IllegalStateException e)
        { e.printStackTrace();  } 
    } 
    if (cmd.equals("stop"))
    { 
        try
        {
            mRecorder.stop();
            mRecorder.reset(); 
        }
        catch (Exception e)
        { e.printStackTrace(); }
    }
    

4 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。我必须创建一个功能initRecorder来设置和准备媒体记录器。然后我每按一次启动按钮但调用start之前调用此函数。停止后recreate()也有效。

    StartRecording.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 100);

            try {
                try {
                    initRecorder(mHolder.getSurface());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mMediaRecorder.start();

                Log.e("mRecorder", "Started");
            } catch (RuntimeException e) {
                Log.e("mRecorder", "Start Failure");
                e.printStackTrace();

            }
        }
    });


private void initRecorder(Surface surface) throws IOException {

    toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 1000);

    if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();

   // mMediaRecorder.setCamera(mCamera);

    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    //       mMediaRecorder.setOutputFormat(8);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    //mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
    mMediaRecorder.setVideoFrameRate(30);
   // mMediaRecorder.setVideoSize(640,480);

    mMediaRecorder.setPreviewDisplay(surface);
    mMediaRecorder.setOutputFile(path);

  // mMediaRecorder.setPreviewDisplay(mHolder.getSurface());
    mMediaRecorder.setMaxDuration(10000); // 10 seconds
    try {
        mMediaRecorder.prepare();
        Log.e("mRecorder", "Prepared");
    } catch (IOException e) {
       Log.e("mRecorder", "Prepare Failure");
        e.printStackTrace();
    }

    mInitSuccesful = true;

}

答案 1 :(得分:0)

在第二个周期中你没有打电话给准备,你需要先调用它才能在媒体录音机上调用启动

答案 2 :(得分:0)

这是一个自我回答,但我不会检查答案,因为它只是解决方法。

根据@Pulkit Sethi,state-1表示MediaRecorder无法正常启动或正常停止。

也许,这是由于本地套接字对象sender.getFileDescriptor()setOutputFile的目标。

到目前为止,它太复杂了,我找不到足够优雅地重新启动或重新使用MediaRecorder的方法,我选择每次都处理掉。

所以 周期是

  1. 启动localSocket / Server
  2. 连接到localSocket / set options / mRecorder.prepare();
  3. mRecorder.start();
  4. 停止/关闭/释放整个
  5. 这看起来不是最聪明的方式,但至少简单而稳定,我很满意开始/停止的结果/&按预期重新开始。

       if (cmd.equals("stop"))
    
        try
        {
            if (sender != null)
            {
                sender.close();
            }
            if (receiver != null)
            {
                receiver.close();
            }
            if (server != null)
            {
                server.close();
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();  
        } 
        sender = null;
        receiver = null;
        server = null;  
    }
    

    for MediaRecorder

    mRecorder.release();

答案 3 :(得分:0)

输出文件必须是实际文件,而不是套接字。这是因为MediaRecorder通常需要能够在文件中回溯以在录制结束时更新标题,并且您无法在套接字中寻找。