【问题标题】:MediaRecorder issue on Android LollipopAndroid Lollipop 上的 MediaRecorder 问题
【发布时间】:2015-01-15 10:26:09
【问题描述】:

我正在新的 Android Lollipop 上测试 libstreaming,而在之前版本中运行的这段代码似乎启动了异常。

    try {
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setCamera(mCamera);

        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mMediaRecorder.setVideoEncoder(mVideoEncoder);
        mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
        mMediaRecorder.setVideoSize(mRequestedQuality.resX,mRequestedQuality.resY);


        mMediaRecorder.setVideoFrameRate(mRequestedQuality.framerate);

        // The bandwidth actually consumed is often above what was requested 

        mMediaRecorder.setVideoEncodingBitRate((int)(mRequestedQuality.bitrate*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();
        mMediaRecorder.start();

    } catch (Exception e) {
        throw new ConfNotSupportedException(e.getMessage());
    }

启动的异常是:

MediaRecorder:启动失败 -38

11-18 09:50:21.028: W/System.err(15783): net.majorkernelpanic.streaming.exceptions.ConfNotSupportedException
11-18 09:50:21.028: W/System.err(15783):    at net.majorkernelpanic.streaming.video.VideoStream.encodeWithMediaRecorder(VideoStream.java:442)
11-18 09:50:21.028: W/System.err(15783):    at net.majorkernelpanic.streaming.MediaStream.start(MediaStream.java:250)

我已尝试发表评论:

mMediaRecorder.setOutputFile(mSender.getFileDescriptor());

没有异常启动,但是当我开始流式传输时,一个对话框告诉我需要一个输出文件。

帮助表示赞赏。

【问题讨论】:

  • 我想我遇到了类似的错误。我正在尝试写入本地套接字以流式传输音频/视频,但是在出现 -38 错误 E/StagefrightRecorder :输出文件描述符无效之后。根据android.googlesource.com/platform/frameworks/av/+/master/media/… 第752 行的错误输出。当文件描述符小于0 时,意味着-1 默认哨兵值。除了我在设置输出文件之前验证我将描述符设置为 136。
  • 你用的是哪个安卓版本?
  • 这个问题只在棒棒糖上。当它们在 kitkat 上时,相同的 nexus 5 和相同的 nexus 7 设备上的相同代码可以工作。我现在很确定问题与套接字有关,但我仍在努力寻找可能发生的变化。
  • 对我来说也是如此...不幸的是,直到现在在网络上都没有找到任何东西...
  • 在 Android 5.0 中使用 ParcelFileDescriptor 效果很好,但我在使用 MediaRecorder 时遇到了视频颜色问题。颜色与实际颜色和以前的 Android 版本不同。我认为颜色格式错误。你遇到了吗@andreasperelli?

标签: android exception streaming mediarecorder


【解决方案1】:

我提交了一份关于 AOSP 的错误报告。 https://code.google.com/p/android/issues/detail?id=80715

“当前的 SELinux 政策不允许 mediaserver 处理应用程序生成的抽象 unix 域套接字。

相反,我建议您创建 Android 5.0 政策允许的管道对 (http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#createPipe())。 " 我不知道他们为什么这样做,也不知道我们应该怎么知道。

我正在使用一个非常旧/修改(无法判断)的 libstreaming 版本,其中 mediastream 仍然从 mediarecorder 扩展,但是查看当前版本,在 MediaStream 中您可能希望将 createSockets 更改为包括以下:

        ParcelFileDescriptor[] parcelFileDescriptors =ParcelFileDescriptor.createPipe();
        parcelRead = new ParcelFileDescriptor(parcelFileDescriptors[0]);
        parcelWrite  = new ParcelFileDescriptor(parcelFileDescriptors[1]);

然后在您的视频/音频流中

setOutputFile(parcelWrite.getFileDescriptor());

在同一个文件中 改变

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

            InputStream is = null;
            try{ is = new ParcelFileDescriptor.AutoCloseInputStream(parcelRead);
            }
            catch (Exception e){}
            mPacketizer.setInputStream(is);

正如 andreasperelli 在评论中指出的那样,确保在 closeSockets() 中关闭 ParcelFileDescriptors,或者根据您的实现和版本,在 closeSockets() 之前和调用 MediaRecorder.stop() 之前关闭。

【讨论】:

  • 这似乎适用于开始流式传输,停止它我看到 MediaCodecInputStream - No buffer available... in logcat 和 onSessionStopped 似乎没有被调用。顺便说一句,很好的解决方法!
  • 解决了添加:parcelRead.close();和 parcelWrite.close();在 closeSockets() 方法中:-)
  • 在带有 Android 5.0 的 Nexus 4 上运行良好,在带有 Android 5.0 的 Nexus 5 上流式传输是绿色且垃圾...
  • 解决了添加:parameters.set("cam_mode", 1);在 VideoStream.java createCamera() 方法中
  • 能否请您发布解决方案的完整代码?
【解决方案2】:

在 Android 6.0 我用代码解决了这个问题

new Thread(new Runnable() {
  @Override public void run() {
    FileInputStream inputStream = null;
    try {
      inputStream = new FileInputStream(path);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    while (true) {
      byte[] buffer = new byte[0];
      try {
        buffer = new byte[inputStream.available()];
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        inputStream.read(buffer);
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        mSender.getOutputStream().write(buffer);
        mSender.getOutputStream().flush();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}).start();

我使用一个文件作为缓冲区并在另一个线程中写入字节。MediaRecorder 输出到该文件。

【讨论】:

  • 您好,请详细说明如何使用此代码。
猜你喜欢
  • 2015-02-10
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
相关资源
最近更新 更多