我正在尝试通过本地Socket从Android的MediaRecorder发送h264 / AAC视频。目标是通过RTMP或RTSP将视频发送到WOWZA服务器,但它给我带来了很多麻烦,而现在我只是试图将数据写入LocalServerSocket中的文件。
这是一些代码。对不起,它不是很干净,但我花了好几个小时测试很多东西,现在我的项目很乱。
在Camera活动中,输出文件设置:
LocalSocket outSocket = new LocalSocket();
try {
outSocket.connect(new LocalSocketAddress(LOCAL_SOCKET));
} catch (Exception e) {
Log.i(LOG_TAG, "Error connecting socket: "+e);
}
mMediaRecorder.setOutputFile(outSocket.getFileDescriptor());
LocalServerSocket实现:
try {
mLocalServerSocket = new LocalServerSocket(mName);
} catch (Exception e) {
Log.e(LOG_TAG, "Error creating server socket: "+e);
return;
}
while (true) {
File out = null;
FileOutputStream fop = null;
try {
mLocalClientSocket = mLocalServerSocket.accept();
InputStream in = mLocalClientSocket.getInputStream();
out = new File(mContext.getExternalFilesDir(null), "testfile.mp4");
fop = new FileOutputStream(out);
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) >= 0) {
Log.i(LOG_TAG, "Writing "+len+" bytes");
fop.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
try {
fop.close();
mLocalClientSocket.close();
} catch (Exception e2) {}
}
}
问题是任何媒体播放器都无法读取由此产生的文件。你认为这是因为编码问题吗?如果我理解的话,这段代码应该生成一个二进制文件?!
先谢谢,欢呼。
答案 0 :(得分:2)
好的,我已经找到了文件无法播放的原因。在MP4和3GPP文件中,有一个包含字节的标头:
在HEX中ftyp3gp4 3gp43gp6宽mdat
0000001866747970336770340000030033677034336770360000000877696465000392D86D6461740000
'mdat'标记之前的4个字节表示位于文件末尾的另一个'moov'标记的位置。通常在录制结束时设置位置,但由于MediaRecorder无法搜索套接字,因此在我们的情况下,它无法将这些字节设置为正确的值。
我现在的问题是找到一种方法使这样的文件可以流式传输,因为它涉及在录制结束之前播放它。
答案 1 :(得分:1)
您可以尝试使用mp4box重新构建文件。 moov框为每个音频和视频样本提供索引。如果它位于文件的末尾,则会使其难以流式传输。
这可能会有所帮助: http://boliston.wordpress.com/tag/moov-box/
或者这个: mp4box -inter 0.5 some_file.mp4
(我目前没有机会尝试)
如果您需要使用此应用程序,我不知道将mp4box移植到Android的任何活动。
答案 2 :(得分:0)
我今天尝试做同样的事情,但是mp4并不是很容易流式传输(如前所述,有些部分是在最后写的)。我不能说这是不可能的,但似乎至少相当困难。
因此,针对较新的Android API(4.3)的解决方法可能是:
此解决方案的缺点是相机的预览尺寸可能小于视频尺寸。这意味着根据您的设备,您无法以最高分辨率录制。提示:有些相机表示他们不支持更高的预览尺寸,但他们会这样做,您可以尝试配置相机以将预览尺寸设置为视频尺寸。如果这样做,请捕获camera.setParameters的RuntimeException,如果失败则仅使用支持的预览大小。
一些链接如何从SurfaceTexture记录:
Bigflage: great examples for MediaCodec stuff.
The VideoRecorder class from Lablet.
也可能有用:spydroid-ipcamera将来自MediaRecorder套接字的数据作为RTP流进行流式传输,但我发现无法将其提供给MediaCodec。 (我已经卡住了读正确的NAL单位尺寸......)