2013-02-24 4 views
1

Я пытаюсь записать только видео (H264/3gpp) с помощью MediaRecorder и передал дескриптор LocalSocket в MediaRecorder. Я могу получать данные, но не могу воспроизвести видео. Тот же код работает для аудио (AMR).Не удается воспроизвести видео, полученное от LocalSocket в android

LocalSocket класс

public class MediaStreamer extends MediaRecorder{ 

    private static int id = 0; 

    private LocalServerSocket lss = null; 
    private LocalSocket receiver, sender = null; 

    public void prepare() throws IllegalStateException,IOException { 

     receiver = new LocalSocket(); 
     try { 
      lss = new LocalServerSocket("librtp-"+id); 
      receiver.connect(new LocalSocketAddress("librtp-"+id)); 
      receiver.setReceiveBufferSize(4096); 
      receiver.setSendBufferSize(4096); 
      sender = lss.accept(); 
      sender.setReceiveBufferSize(4096); 
      sender.setSendBufferSize(4096); 
      id++; 
     } catch (IOException e1) { 
      throw new IOException("Can't create local socket !"); 
     } 

     setOutputFile(sender.getFileDescriptor()); 

     try { 
      super.prepare(); 
     } catch (IllegalStateException e) { 
      closeSockets(); 
      throw e; 
     } catch (IOException e) { 
      closeSockets(); 
      throw e; 
     } 

    } 

    public InputStream getInputStream() { 

     InputStream out = null; 

     try { 
      out = receiver.getInputStream(); 
     } catch (IOException e) { 
     } 

     return out; 

    } 


    public void stop() { 
     closeSockets(); 
     super.stop(); 
    } 

    private void closeSockets() { 
     if (lss!=null) { 
      try { 
       lss.close(); 
       sender.close(); 
       receiver.close(); 
      } 
      catch (IOException e) { 

      } 
      lss = null; sender = null; receiver = null; 
     } 
    } 
} 

MediaRecorder

video = new MediaStreamer(); 
video.reset(); 

video.setVideoSource(MediaRecorder.VideoSource.DEFAULT); 
video.setPreviewDisplay(holder.getSurface()); 
video.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
video.setVideoFrameRate(VideoConstants.frameRate); 
video.setVideoEncodingBitRate(VideoConstants.bitRate*1000); 
video.setVideoSize(VideoConstants.resolationX, VideoConstants.resolationY); 
video.setVideoEncoder(MediaRecorder.VideoEncoder.H264); 

try { 
    video.prepare(); 
    videoWriter = new Writer(Environment.getExternalStorageDirectory()+"/video.mp4",video.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
video.start(); 
videoWriter.startWriting(); 

ответ

1

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

Основная проблема заключается в том, что 3GPP (например, MP4) не является живым, потоковым форматом, поэтому даже если данные захватываются через сокет, важные заголовки файлов, которые обычно записываются в конце аудио- или видеозахвата , отсутствуют (поскольку сокеты не видны, как локальные файлы), следовательно, невоспроизводимые данные.

AMR не имеет этого ограничения заголовка файла, поэтому аудиозапись OP отлично работает с кодом выше.

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

  1. не использует 3GPP или MP4 в качестве формата запись
  2. написать packetiser подобного тому, что используется в Spydroid project

Надеется, что это помогает.

1

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

Проверить Spydroid, который делает подобную вещь

1

Вы могли бы использовать этот пример, чтобы удалить заголовок MP4:

InputStream reader = video.getInputStream(); 
byte buffer[] = new byte[4]; 
while (!Thread.interrupted()) { 
    while (reader.read() != 'm'); 
     reader.read(buffer,0,3); 
     if (buffer[0] == 'd' && buffer[1] == 'a' && buffer[2] == 't') break; 
} 

Я видел этот код в Lib libstreaming (VideoStream.java). Это тот же самый lib, используемый в Spydroid.

Смежные вопросы