android - 从 Android Media Recorder 流式传输后修复 3GP 文件

标签 android video video-streaming 3gp android-mediarecorder

我正在尝试通过本地 unix 套接字从 android 相机流式传输视频,并将文件从流写入 sdcard。一切正常,除了文件不能用任何播放器播放。这是因为 Android 没有填补文件中的一些空白,因为套接字不可搜索。据我了解,我需要在视频流结束后进行一些修改。我看了好几篇文章here , herehere ,但他们都没有帮助我。我正在玩十六进制编辑器以学习如何手动执行此操作,因此之后在 Android 代码中执行相同操作将变得微不足道。

这是从流中保存的示例文件:https://dl.dropbox.com/u/17510473/sample_not_playable.3gp

任何人都可以修复它使其可以播放并告诉他他是如何做到的吗?

编辑:我删除 3gp 文件的 header 并按如下方式编写新文件:

00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 00 00 00

然后我使用以下命令找到 mdat 和 moov 原子的起始位置:

grep -aobE "ftyp|mdat|moov" sample_not_playable.3gp

它给了我以下输出:

4:ftyp
28:mdat
1414676:moov

然后使 1414676 - 28 = 1,414,648 = 0x1595F8

然后我将 0x1595F8 写为 25-28 字节,就在 mdat 原子之前。所以我的标题现在看起来像这样:

00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 15 95 F8

当我尝试用 mplayer 播放它时,我得到了一些损坏的视频和音频输出。以下是 mplayer 输出的部分内容:

[amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file?
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file?
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
A:  11.0 V:   1.4 A-V:  9.650 ct:  0.023   0/  0 10%  1%  1.6% 0 0                                                        
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f72adeafc40]stream 1, offset 0x15e62b: partial file
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
A:  11.1 V:   1.5 A-V:  9.558 ct:  0.027   0/  0  9%  1%  1.4% 0 0                                                        
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!

我做错了什么?

最佳答案

您需要了解的是,mp4 不是一种直播 流媒体格式。因此,无论如何您都无法破解以使其可以直播。 header [moov atom]写在最后。 Android 在内存中创建一个包含帧大小和其他参数的表,然后在录制结束时将其写入文件的开头,因此它需要文件句柄的可查找性。 [哪个套接字不是]

如果您正在将加密的内容写入磁盘并且您希望这样做以便没有人可以播放该文件,则您不必加密整个文件。您只需加密 header ,整个文件就无法播放。

如果您因为不相信我之前的段落而迫切需要完整的文件编码,那么请使用 ffmpeg 之类的东西来进行编码。修改它给你加密输出本身并再次将它保存到硬盘 - 再次删除套接字部分。

在 Android 中您无法实时流式传输 mp4 文件。我见过很多人徒劳地尝试它,如果你了解视频/格式,你就无法做到。 mp4 不是为直播而设计的。除非您事先知道您的帧大小 [您不知道] 和编码的确切长度 [您很可能不知道;t] 您不能预先创建标题。

附言。 mp4 和 3gp 是堂兄弟,所以同样适用。

许多人将直播与http pd和伪流混为一谈。实时流式传输意味着我没有整个文件,它正在创建并且也在运行中进行流式传输。 http pd 和伪流发生在完全可用的文件上。

编辑:

如果您的目标是在存储到 SD 卡之前加密录制的文件,您需要编码器支持。这意味着在其中安装您自己的编码器。以 ffmpeg 为例,将其交叉编译为 android。为您的应用程序编写一个小型 JNI 接口(interface)。不加密先搞定这个。完成后,在 ffmpeg fwrites 流中,添加您的加密模块。解码时也是一样。 Y3ng 创作。这是最干净的方法。

编辑 2: 请参阅 spydroid 以获得一些适合您的功能。那里有类似的。

编辑 3:为了提高答案的质量,我正在解释其他答案也给出的不完美的解决方法:

人们仍然可以通过解析生成的 mp4 并通过套接字单独发送基本流来流式传输 AV。您将面临的唯一问题是您无法获得完美的 AV 同步,因为您不知道确切的 AV 样本时间戳。只有 android 知道这一点,并将其写入末尾的 mp4 header 中。所以对你没有好处。您必须假设视频帧的完美采样率,并且您的音频必须是 amr 才能假设 20ms 数据包。在其他音频案例中,您会开始看到长时间的漂移 [尤其是当您开始出现高动态场景时]。这是因为每个生成的音频包并不对应固定的时长[amr等语音编解码器除外]

关于android - 从 Android Media Recorder 流式传输后修复 3GP 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11994470/

相关文章:

php - 使用YouTube API V3 PHP获得视频分级

ffmpeg - 从网络访问ffmpeg m3u8文件

video-streaming - 检测MPEG TS流中的视频帧类型

android - 在 Android 中将图像复制到剪贴板

java - Android 在充电时禁用显示屏

android - JSON解析错误: No value for JSON array

HTML5 直播

Java方法参数类型和接口(interface)一致性

java - 如何提高使用 Xuggler 制作的视频的质量

ruby-on-rails - 仅允许视频嵌入代码 (Rails)