如何通过网络流式传输摄像机流,生成有效的视频文件,使用Android?

时间:2014-05-03 00:17:35

标签: android stream mediarecorder

我尝试将摄像机录制内容写入网络流,请参阅以下代码段:

ParcelFileDescriptor fd = ParcelFileDescriptor.fromSocket(socket);
this.camera.lock(); // this.camera refers to an android.hardware.Camera instance.
this.camera.unlock();
this.mediaRecorder = new MediaRecorder();
this.mediaRecorder.setCamera(this.camera);
this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
this.mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
this.mediaRecorder.setOutputFile(fd.getFileDescriptor());
this.mediaRecorder.prepare();
this.mediaRecorder.start();

然后我试图在连接的另一端捕获它:使用Socket.getInputStream()我正在读取字节,是的,字节进来。字节实际上是通过网络写的。

但是当尝试使用FileOutputStream类将其保存到文件中,并使用VLC打开文件时,它就无法读取。

我怎样才能最终制作文件' playable',这意味着它是一个有效的视频文件?

编辑:

当我使用this.mediaRecorder.setOutputFile("/sdcard/out.mp4");时,我可以在Android中打开视频文件,它会成功播放。 但是,当我使用this.mediaRecorder.setOutputFile(fd.getFileDescriptor());时,它就赢了。

1 个答案:

答案 0 :(得分:4)

问题可能是由于您没有在摄像机配置文件中设置所有内容。

而不是:

this.mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));

试试这个例子:

CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
profile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
this.mediaRecorder.setProfile(profile);

顺便说一句,您是在尝试完录制视频后传输此视频,还是在从摄像机获取数据时实时传输?

编辑:

如果我没记错,mpeg4文件格式没有页脚,所以不需要"等待整个文件" ...但是:这种类型的文件有一个你无法打破的结构如果你想阅读它因此,如果您发送以mpeg4文件格式准备的视频的原始字节,并且您希望在收到这些字节的随机数后打开文件,则可能会出现问题。你几乎可以肯定,你不会幸运地收到你视频的正确字节数。

我建议你做的是:

  1. 检查一下。例如:将一些视频发送到另一端并使用某种允许您检查文件结构的软件。也许其中一个会告诉你文件是否具有正确的结构。我可以尝试链接一些工具,但我自己还没有尝试过任何一种工具,所以你可能需要寻找其他东西(如果它们都不能正常工作)。 您可以尝试举例thisthat

  2. 如果步骤1.确认您的文件被剪切到错误的位置,那么您可以尝试以某种方式控制它。例如,通过向接收者通知文件的位置,当用于切割文件时,不会导致破坏结构(将允许您打开文件)。

  3. 另一种方法是尝试发送某种" raw"视频帧。通过" raw"我的意思是来自相机的某种低级数据,您可以发送并在接收方应用特定的编解码器。我还没有尝试过这样做,所以你可能需要检查它是否可能(获得这种类型的数据)。