凌云志轩
2016-08-23 08:56
采纳率: 89%
浏览 4.4k
已采纳

MediaRecorder(18373): start failed: -38

我在利用手机摄像头录像并通过localsocket推送rtsp流到电脑。现在有时候会出现这个错误MediaRecorder(18373): start failed: -38,出现后很长一段时间后又突然好了,过一段时就又突然出现这个错误。
有时候会出现如下错误才会提示start failed: -38,我觉得和这个有关系

 08-23 11:30:00.871: E/ACodec(12103): [OMX.google.h264.encoder] ERROR(0x80001001)
08-23 11:30:00.871: E/ACodec(12103): signalError(omxError 0x80001001, internalError -2147483648)
08-23 11:30:00.871: E/MediaCodec(12103): Codec reported err 0x80001001, actionCode 0, while in state 6
08-23 11:30:00.921: E/ACodec(12103): [OMX.google.h264.encoder] ERROR(0x80001001)
08-23 11:30:00.921: E/ACodec(12103): signalError(omxError 0x80001001, internalError -2147483648)
08-23 11:30:00.921: E/MediaCodec(12103): Codec reported err 0x80001001, actionCode 0, while in state 6
08-23 11:30:01.061: E/ACodec(12103): [OMX.qcom.video.encoder.avc] storeMetaDataInBuffers (output) failed w/ err -1010

网上看到是那个service在后台用到它,所以才会报错么,但是我从后台退出程序,再次进入依然保这个错误,我很费解,哪位大神帮我看看,跪求指点。

断点刚到这个方法(还未执行这个方法),摄像头正常工作。

创建MediaRecorder代码如下。

MediaRecorder mMediaRecorder = null;
 protected void encodeWithMediaRecorder() throws IOException {
        Log.d(TAG,"Video encoded using the MediaRecorder API");

        // We need a local socket to forward data output by the camera to the packetizer
        createSockets();

        // Reopens the camera if needed
        destroyCamera();
        createCamera();

        // The camera must be unlocked before the MediaRecorder can use it
        unlockCamera();

        if (mMediaRecorder != null)
        {
            mMediaRecorder.stop();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
//      try {

            mMediaRecorder = new MediaRecorder();
            //mCamera.unlock();
            mMediaRecorder.setCamera(mCamera);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setVideoEncoder(mVideoEncoder);

            mMediaRecorder.setVideoSize(mRequestedQuality.resX,mRequestedQuality.resY);
            mMediaRecorder.setVideoFrameRate(mRequestedQuality.framerate);
            mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
            // The bandwidth actually consumed is often above what was requested 
            mMediaRecorder.setVideoEncodingBitRate((int)(mRequestedQuality.bitrate*0.8));//0.8

            // We write the ouput of the camera in a local socket instead of a file !           
            // This one little trick makes streaming feasible quiet simply: data from the camera
            // can then be manipulated at the other end of the socket
            mMediaRecorder.setOutputFile(mSender.getFileDescriptor());

            mMediaRecorder.prepare();
            try{
                mMediaRecorder.start(); 这里抛出异常start failed: -38
            }catch(Exception e)
            {
                Log.e(TAG,"this is Exception start error : "+e); //这里只打印到java.lang.IllegalStateException
            }

//      } catch (Exception e) {
//          Log.e(TAG,"this is Exception error : "+e);
//          throw new ConfNotSupportedException(e.getMessage());
//      }

        // This will skip the MPEG4 header if this step fails we can't stream anything :(
        InputStream is = mReceiver.getInputStream();
        try {
            byte buffer[] = new byte[4];
            // Skip all atoms preceding mdat atom
            while (!Thread.interrupted()) {
                while (is.read() != 'm');
                is.read(buffer,0,3);
                if (buffer[0] == 'd' && buffer[1] == 'a' && buffer[2] == 't') break;
            }
        } catch (IOException e) {
            Log.e(TAG,"Couldn't skip mp4 header :/");
            stop();
            throw e;
        }

        // The packetizer encapsulates the bit stream in an RTP stream and send it over the network
        mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
        mPacketizer.setInputStream(mReceiver.getInputStream());
        mPacketizer.start();

        mStreaming = true;

    }

    protected void createSockets() throws IOException {

        final String LOCAL_ADDR = "net.majorkernelpanic.streaming-";

        for (int i=0;i<10;i++) {
            try {
                mSocketId = new Random().nextInt();
                mLss = new LocalServerSocket(LOCAL_ADDR+mSocketId);
                break;
            } catch (IOException e1) {
                Log.e(TAG, "this is mLss error : " + e1 );
            }
        }

        mReceiver = new LocalSocket();
        mReceiver.connect( new LocalSocketAddress(LOCAL_ADDR+mSocketId));
        mReceiver.setReceiveBufferSize(500000);
        mReceiver.setSoTimeout(3000);
        mSender = mLss.accept();
        mSender.setSendBufferSize(500000);
    }

    protected synchronized void destroyCamera() {
        if (mCamera != null) {
            if (mStreaming) super.stop();
            lockCamera();
            mCamera.stopPreview();
            try {
                mCamera.release();
            } catch (Exception e) {
                Log.e(TAG,e.getMessage()!=null?e.getMessage():"unknown error");
            }
            mCamera = null;
            mCameraLooper.quit();
            mUnlocked = false;
            mPreviewStarted = false;
        }   
    }

    protected boolean mUnlocked = false;
    protected synchronized void createCamera() throws RuntimeException {
        if (mSurfaceView == null)
            throw new InvalidSurfaceException("Invalid surface !");
        if (mSurfaceView.getHolder() == null || !mSurfaceReady) 
            throw new InvalidSurfaceException("Invalid surface !");

        if (mCamera == null) {
            openCamera();
            mUnlocked = false;
            mCamera.setErrorCallback(new Camera.ErrorCallback() {
                @Override
                public void onError(int error, Camera camera) {
                    // On some phones when trying to use the camera facing front the media server will die
                    // Whether or not this callback may be called really depends on the phone
                    if (error == Camera.CAMERA_ERROR_SERVER_DIED) {
                        // In this case the application must release the camera and instantiate a new one
                        Log.e(TAG,"Media server died !");
                        // We don't know in what thread we are so stop needs to be synchronized
                        mCameraOpenedManually = false;
                        stop();
                    } else {
                        Log.e(TAG,"Error unknown with the camera: "+error);
                    }   
                }
            });

            try {

                // If the phone has a flash, we turn it on/off according to mFlashEnabled
                // setRecordingHint(true) is a very nice optimisation if you plane to only use the Camera for recording
                Parameters parameters = mCamera.getParameters();
                if (parameters.getFlashMode()!=null) {
                    parameters.setFlashMode(mFlashEnabled?Parameters.FLASH_MODE_TORCH:Parameters.FLASH_MODE_OFF);
                }
                parameters.setRecordingHint(true);
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);//1连续对焦  
                mCamera.setParameters(parameters);
                mCamera.setDisplayOrientation(mOrientation);

                try {
                    if (mMode == MODE_MEDIACODEC_API_2) {
                        mSurfaceView.startGLThread();
                        mCamera.setPreviewTexture(mSurfaceView.getSurfaceTexture());
                    } else {
                        mCamera.setPreviewDisplay(mSurfaceView.getHolder());
                        mCamera.setDisplayOrientation(270);
                    }
                } catch (IOException e) {
                    throw new InvalidSurfaceException("Invalid surface !");
                }

            } catch (RuntimeException e) {
                destroyCamera();
                throw e;
            }

        }
    }

    protected void unlockCamera() {
        if (!mUnlocked) {
            Log.d(TAG,"Unlocking camera");
            try {   
                mCamera.unlock();
            } catch (Exception e) {
                Log.e(TAG,"unlockCamera : "+e.getMessage());
            }
            mUnlocked = true;
        }
    }

如果哪里不清楚,我可以再贴代码。现在我一直弄不懂为什么会出现start failed -38,再次跪求指点。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dabocaiqq 2016-08-23 16:08
    已采纳
    点赞 打赏 评论
  • 凌云志轩 2016-08-24 01:15

    我的解决办法来自于http://stackoverflow.com/questions/26990816/mediarecorder-issue-on-android-lollipop

    我原来出问题的代码

     protected LocalSocket mReceiver = null, mSender = null;
     private LocalServerSocket mLss = null;
        private int mSocketId, mTTL = 64;
        protected void createSockets() throws IOException {
    
            final String LOCAL_ADDR = "net.majorkernelpanic.streaming-";
    
            for (int i=0;i<10;i++) {
                try {
                    mSocketId = new Random().nextInt() +i;
                    mLss = new LocalServerSocket(LOCAL_ADDR+mSocketId);
                    break;
                } catch (IOException e1) {}
            }
    
            mReceiver = new LocalSocket();
            mReceiver.connect( new LocalSocketAddress(LOCAL_ADDR+mSocketId));
            mReceiver.setReceiveBufferSize(500000);
            mReceiver.setSoTimeout(3000);
            mSender = mLss.accept();
            mSender.setSendBufferSize(500000);
        }
    
    

    现在改为

     protected void createSockets() throws IOException {
    
            final String LOCAL_ADDR = "net.majorkernelpanic.streaming-";
    
            for (int i=0;i<10;i++) {
                try {
                    mSocketId = new Random().nextInt() +i;
                    mLss = new LocalServerSocket(LOCAL_ADDR+mSocketId);
                    break;
                } catch (IOException e1) {}
            }
    
    //      mReceiver = new LocalSocket();
    //      mReceiver.connect( new LocalSocketAddress(LOCAL_ADDR+mSocketId));
    //      mReceiver.setReceiveBufferSize(500000);
    //      mReceiver.setSoTimeout(3000);
    //      mSender = mLss.accept();
    //      mSender.setSendBufferSize(500000);
             ParcelFileDescriptor[] parcelFileDescriptors =ParcelFileDescriptor.createPipe();
             ParcelFileDescriptor parcelRead = new ParcelFileDescriptor(parcelFileDescriptors[0]);
             ParcelFileDescriptor parcelWrite = new ParcelFileDescriptor(parcelFileDescriptors[1]);
        }
    
    

    把mPacketizer.setInputStream(mReceiver.getInputStream());改为
    InputStream is = null;
    try{ is = new ParcelFileDescriptor.AutoCloseInputStream(parcelRead);
    }
    catch (Exception e){}
    mPacketizer.setInputStream(is);
    把mMediaRecorder.setOutputFile(mSender.getFileDescriptor()); 改为把mMediaRecorder.setOutputFile(parcelWrite.getFileDescriptor());

    然后一切正常了,然而缺出现了一个新问题:就是出现花屏了。以前的代码虽然时儿会报错,但是运行出来结果后是不会出现花屏的,分辨率是1280*720,改后的代码感觉视频效果非常差劲。这是为什么呢?

    点赞 打赏 评论

相关推荐 更多相似问题