Подтвердить что ты не робот

Проблема MediaRecorder на Android Lollipop

Я тестирую libstreaming на новом Android Lollipop, и этот код который работал над предыдущим выпуском, похоже, запускает исключение.

    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());

не было запущено никаких исключений, но когда я начну передавать потоки, сообщите мне, что нужен выходной файл.

Помогите оценить.

4b9b3361

Ответ 1

Я подал сообщение об ошибке в AOSP. https://code.google.com/p/android/issues/detail?id=80715

"Текущие политики SELinux не позволяют медиасерверу обрабатывать сгенерированные сгенерированные абстрактные сокеты домена unix.

Вместо этого я рекомендую вам создать пару-тройку (http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#createPipe()), которая разрешена политикой Android 5.0. " Я не знаю, почему они это сделали или как мы должны были знать.

Я использую очень старую/модифицированную (не могу сказать) версию 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 в комментарии, обязательно закройте ParcelFileDescriptors в closeSockets() или в зависимости от вашей реализации и версии перед closeSockets() и перед вызовом MediaRecorder.stop().

Ответ 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 в файл.