如何在mp4视频文件中添加MOOV原子

53

我正在处理Android上的设备到服务器流式传输,我能够将数据以字节形式发送到服务器,但当我在服务器上播放录制的文件时,VLC会提示找不到MOOV原子。经过多次尝试,我发现mp4文件的MOOV原子在最后生成。但我必须在录制的同时在服务器上播放该文件。我查看了SPYDROIDSIPDROID的源代码,但它们都无法正常工作。我尝试使用FFMPEG在服务器端添加moov原子,但没有成功。请问有人知道如何做到这一点吗?


我能否使用FFmpeg来解决在Plex上播放电视剧时遇到的问题。日志显示: - markum
为了更清楚,我正在树莓派4上运行我的Plex和NAS服务器。我正在使用“MacX DVD Ripper Pro”来提取视频。我升级到最新版本的Plex(1.21.1.3830),这应该允许一个新的扫描程序。 - markum
7个回答

36

有一个叫做untrunc的工具,声称可以修复未完成(截断)的mp4、m4v、mov和3gp视频。我自己没有测试过,但值得一试。


2
对于Windows用户,请使用以下链接:https://www.videohelp.com/software/recover-mp4-to-h264 - user136036
32
这经常对我的视频不起作用,但我使用了Anthon Lockwood的fork获得了成功:它包含一个"-s"开关,可以"遍历未知序列"。 - Johannes
3
测试了其他软件,但只有这个软件修复了我的损坏文件。祝贺它的开发者!还有 @k3a:谢谢你的提示。 - Zsolti
1
甚至有一个在线服务可以实现这一点 http://untrunc.it/ - Roman
1
如果您不想从源代码构建它,可以从Snap安装fork - oeter

24

你遇到了一个问题。'moov'箱是一种目录表,如果不是所有内容都在那里,你就无法拥有完整的目录表。哎呀!

如果你想继续使用MP4并且是自己编写文件,那么你可以将文件写成所谓的分段MP4文件。分段MP4文件包含多个独立的小视频片段 - 每个片段都有自己的目录表。这将使您能够在完成整个记录之前播放该文件。

如果您不需要使用MP4,则可以选择将原始h264流写入服务器。然后您就没有这种目录表的问题了。VLC可以播放原始h264流。


你好Sebastian,我在Android视频录制时无法获取行数据,你能告诉我如何实现吗? - Ravinder
我了解MP4,但不是特别了解Android。也许你应该创建一个新的问题。 - Sebastian Annies
另一种方法可能是仅记录一两秒钟,然后在服务器上再次连接?! - Sebastian Annies

14

使用 FFMpeg,可以将 moov 原子移动到视频文件的开头。

ffmpeg -i input_video_file.mp4 -vcodec copy -acodec copy -movflags faststart output_video_file.mp4

这是一个快速参考指南:https://gist.github.com/jaydenseric/220c785d6289bcfd7366 - Abdullah Farweez
3
这里有一个打字错误,“+faststart” 应该改为 “faststart”,正确的命令是 “ffmpeg -i input_video_file.mp4 -vcodec copy -acodec copy -movflags faststart output_video_file.mp4”。 - Xueshi
29
尽管原帖标题为“添加缺失的moov原子”,但此方法实际上只是将现有的moov从文件末尾移到开头(这实际上是问题中所要求的)。如果你根本没有moov,那么你有一个更大的问题。 - Bob Sammers
谢谢,@BobSammers! - Rouben Tchakhmakhtchian
1
对我来说完美地工作了! - DanB
我将视频文件重命名为input_video_file.mp4并复制粘贴了确切的命令。然而,ffmpeg仍然产生以下错误: [mov,mp4,m4a,3gp,3g2,mj2 @ 0x55601375c0c0]未找到moov原子input_video_file.mp4:处理输入时发现无效数据。 - TJM

4

运行qt_faststart将moov原子移到流的开头。

qt-faststart in.mp4 out.mp4

3
嗨,d33pika。谢谢您的回复,我想在录制视频时将数据发送到服务器,但是录制完成后会生成一个moov原子,所以我认为qt-faststart在这里不会有帮助。 - Ravinder
你解决了问题吗,@Ravinder?我现在正试图做完全相同的事情,但没有看到可行的解决方案。如果你知道一个,请在这里发表评论。 - Oliver Hausler
你如何在安卓中使用qt-faststart?能否有人提供一个代码示例? - Kannan_SJD
3
我尝试了这个,但它显示“文件中的最后一个原子不是moov原子”。 - KansaiRobot
1
encountered non-QT top-level atom (is this a QuickTime file?) [...] - silverdr

2
MP4格式需要moov原子信息才能播放视频,并且生成moov原子需要视频完成,您不能在录制时播放MP4文件,因为您仍然没有创建moov原子部分的所有信息。
您想要做的是某种实时流式传输(边录边播),因此需要使用另一种格式。HLS流和MPEG-DASH将视频存储在微小的块(2秒至10秒)中并发送给用户,这样用户就可以一个接一个地播放许多已完成的文件。
正如@Sebastian Annies所建议的那样,创建许多小的MP4文件并连接它们是相同的方法:拥有小的已完成文件并作为列表播放,在这里您可以获得更多信息什么是分段mp4(fMP4)?它与普通mp4有何不同?

1
使用MP4Box将MOOV原子移动到文件开头并交错流式传输块。
MP4Box test.mp4 test.mp4

17
对我来说不起作用。返回: 错误 - 指定了2个输入名称,请检查用法 MP4Box版本0.5.0-rev4065 - Roman Podlinov
2
难道不应该是 MP4Box -add fixed.mp4 -isma sample.mp4 这样吗?请参考 http://muzso.hu/2012/11/14/tools-to-fix-mp4-videos-so-players-can-start-playback-instantly-without-downloading-the-w - Gwyneth Llewelyn

-6

在你的gradle中添加这个库:compile 'net.ypresto.qtfaststartjava:qtfaststart:0.1.0' 然后

File input = new File(path + "/input.mp4"); // Your input file
File output = new File(path + "/output.mp4"); // Your output file
try{
    if(!output.exists()) // if there is no output file we'll create one
        output.createNewFile();
    }
}catch (IOException e){
    Log.e("TAG", e.toString());
}

try{
    QtFastStart.fastStart(input, output); // Adds moov to your input
                                          // Now your output file is ready to stream!
}catch (QtFastStart.MalformedFileException m){
    Log.e("QT", m.toString());
}catch (QtFastStart.UnsupportedFileException q){
    Log.e("QT", q.toString());
}catch (IOException i){
    Log.e("QT", i.toString());
}

这就是全部


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接