2014-11-18 25 views
19

Yeni Android Lollipop üzerinde libstreaming test ediyorum ve önceki sürümde çalışan bu kod, istisna başlatıyor gibi görünüyor.MediaRecorder issue on 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()); 
    } 

başlatılan istisnadır: Ben başladıklarında bir istisna başlattı

mMediaRecorder.setOutputFile(mSender.getFileDescriptor()); 

ama:

MediaRecorder: Ben yorum yapmak denedim

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) 

-38 başlatılamadı Bir iletişim akışı bana bir outputfile gerek olduğunu söyle.

Yardım edin.

+0

Sanırım benzer bir hata alıyorum. Ben de ses/video akışı için yerel bir soket yazmaya çalışıyorum ama -38 hata E/StagefrightRecorder ﹕ Çıktı dosya tanımlayıcısı geçersiz sonra alıyorum. https://android.googlesource.com/platform/frameworks/av/+/master/media/libmediaplayerservice/StagefrightRecorder.cpp satırındaki hata çıktıları, dosya tanımlayıcısı 0'dan küçük olduğunda, anlam -1'den küçüktür. varsayılan sentinel değeri. Bunun dışında, çıktı dosyasını ayarlamadan önce tanımlayıcıyı 136 olarak ayarladığımı doğrularım. – sbaar

+0

hangi Android sürümünü kullanıyorsunuz? – andreasperelli

+0

Bu sorun sadece Lollipop üzerindedir. Aynı nexus 5 ve aynı nexus 7 cihazındaki aynı kod, kitkattayken çalıştı. Sorun şu ki, sorunun soketlerle bir ilgisi var, ama hala neyin değişebileceğini araştırmaya çalışıyorum. – sbaar

cevap

22

AOSP'ye bir hata raporu gönderdim. https://code.google.com/p/android/issues/detail?id=80715

"Mevcut SELinux'un politikaları uygulaması oluşturulan soyut alanı soketlerine işlemek için MediaServer için izin vermez. Bunun yerine

, sana tarafından izin verilen (http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#createPipe()) bir boru-çifti oluşturmak öneriyoruz Android 5.0 politikası " Bunu neden yaptığını veya nasıl bilmem gerektiğini bilmiyorum.

Mediastream'in hala mediarecorder'dan uzatıldığı, ancak şu anki sürümüne baktığımızda, libstreaming sürümünün çok eski/değiştirilmiş (söyleyemiyorum) sürümünü kullanıyorum, muhtemelen MediaStation'da olmak üzere createSockets'ları değiştirmek isteyebilirsiniz. aşağıdaki:

video/ses akışı

setOutputFile(parcelWrite.getFileDescriptor()); 

ve aynı dosyada değişim içinde sonra

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

andreasperelli gibi

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

yorumunda işaret

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

için, closeSockets içinde ParcelFileDescriptors() kapatmak için emin olun, ya da (closeSockets önce uygulamanız ve sürümüne bağlı olarak) ve MediaRecorder.stop aramadan önce(). Ben kodu

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

ile bu sorunu çözmek Android 6.0 de

+0

, createSockets() yöntemini nasıl değiştirdiğinizi görmek için lütfen MediaStream.java kodunu yapıştırabilir misiniz? – andreasperelli

+0

Üzgünüm, net değildim. CreateSockets() ve closeSockets() 'ı yalnız bırakabilir ve sadece bunların içindeki kodu dikkate almazsınız. LocalSockets kullanmıyorsunuz. Bunun yerine, mediastream'de korumalı parselRead ve parcelWrite vars yaratın, bunları yukarıda gösterildiği gibi createSockets'da başlatın ve bunları lokal soketlerin kullanıldığı yerde kullanın, çıktıFile ve packetizer giriş akışı – sbaar

+1

'u ayarlarken yukarıdaki kodun yerini aldığınızda akış, durduğunda MediaCodecInputStream - arabellekte kullanılabilir arabellek yok ve SessionStopped görünmüyor gibi görünüyor. Bu arada, harika düzeltme! – andreasperelli

0

Ben tampon olarak bir dosyayı kullanmak ve dosyaya başka thread.the MediaRecorder çıkışta bayt yazma.

+0

Merhaba, lütfen bu kodu nasıl daha ayrıntılı olarak kullanacağınızı açıklayın. –

İlgili konular