如何在不重新编码H264视频流的情况下通过ffmpeg将.MTS文件(AVCHD)转换为.mp4?


20

注意:不久之前,当我还没有找到这个社区时,我向stackoverflow发布了相同的问题。我重新发布此问题,因为该问题更适合该社区。

1.我尝试过的

我的AVCHD摄像机记录了一些.MTS(AVCHD格式)文件。其规格如下所示:

$ ffprobe 140612_Canon-00000.MTS 
ffprobe version 2.2.1 Copyright (c) 2007-2014 the FFmpeg developers
(snip)
Input #0, mpegts, from '140612_Canon-00000.MTS':
  Duration: 00:48:58.40, start: 0.800300, bitrate: 5563 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), 
      yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 
      29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 
      stereo, fltp, 256 kb/s

注意帧率/时基部分:29.97 fps,29.97 tbr,90k tbn,59.94 tbc

现在,我想将此文件转换为.mp4文件,而无需重新编码H264视频流,而将其音频流转换为AAC。所以我尝试了以下命令:

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

2.结果

输出文件的规格如下所示:

$ ffprobe 140612_Canon-00000.MTS.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100

  Duration: 00:01:00.04, start: 0.021333, bitrate: 4590 kb/s

    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
        1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
        59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : VideoHandler

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 
        48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

查看帧率/时基部分:59.94 fps,59.94 tbr,90k tbn,59.94 tbc。尽管ffmpeg只是复制了视频流,但帧速率和时基已更改为value的两倍

因此,当我使用QuickTime Player或VLC Player打开并播放输出文件时,音频没有问题,但是,视频流无法正确播放。播放视频时,其帧反复向前和向后颤抖。

3.问题

  1. 如何在不正确重新编码H264视频流的情况下通过ffmpeg将.MTS文件(AVCHD)转换为.mp4
  2. 使用和转换容器时,如何保持原始帧速率/时基值(fps / tbr / tbn / tbc)ffmpeg-vcodec copy
  3. 如何通过ffmpeg的命令行选项设置帧速率/时基值(fps / tbr / tbn / tbc),而无需重新编码视频流。

有任何想法吗?


4.添加-r 29.97选项

斯帕克斯教授给我一个建议-r 29.97。我尝试过:

ffmpeg -i 140612_Canon-00001.MTS -t 60 -r 29.97 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

但是,输出文件的帧率/时基仍然错误:

Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
59.94 fps, 59.94 tbr, 11988 tbn, 59.94 tbc (default)

5.使用MP4Box重混

根据Sparkles教授的建议,我使用MP4Box尝试了多路复用和remux。

brew install mp4box

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vcodec copy -an 140612_Canon-00000.MTS.h264

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vn -acodec libfaac -ab 128k 140612_Canon-00000.MTS.aac

mp4box -add 140612_Canon-00000.MTS.h264:fps=29.97 \
  -add 140612_Canon-00000.MTS.aac \
  -new 140612_Canon-00000.MTS.mp4

输出为:

$ ffprobe 140612_Canon-00000.MTS.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
(snip)
  Duration: 00:02:00.22, start: 0.000000, bitrate: 2293 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), 
          yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 2228 kb/s, 
          29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      creation_time   : 2014-07-14 00:38:23
      handler_name    : 140612_Canon-00000.MTS.h264:fps=29.97
       - Imported with GPAC 0.5.0-rev4065

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 
          stereo, fltp, 125 kb/s (default)

看起来有点向前。看一下帧率/时基的一部分:29.97 fps,29.97 tbr,30k tbn,59.94 tbc。那些与原始流匹配,除了tbn(容器的时基值)。

但是,当我使用Quicktime Player或VLC播放输出文件时,视频以一半速度播放

尽管原始文件的90k tbn速度为每秒90000次滴答声,而MP4Box的新输出文件的速度30k tbn仅为原始值的三分之一,但输出文件的播放速度为一半。

我不知道为什么。但我认为剩下的问题是如何调整tbn价值。


5-b。MediaInfo关于输出文件的报告

我还在5. Remux使用MP4Box生成的输出文件上尝试了MediaInfo工具。输出在这里:https : //gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6.尝试avconv

Volodya报告说avconv效果很好。我还准备了用同一台摄像机录制的短样本电影文件(Canon-00006.MTS)。好的,让我们尝试:

brew install avconv
avconv -i Canon-00006.MTS -c:a copy -c:v copy -y Canon-00006.MTS.mp4
ffprobe Canon-00006.MTS.mp4

输出文件的ffprobe信息位于此处:https ://gist.github.com/kaorukobo/5b53244ade2632ff1211 及其帧速率/时基信息如下:59.94 fps,59.94 tbr,90k tbn,59.94 tbc

据Volodya报道,输出文件在VLC Player中播放良好。但是,使用Quicktime Player X打开该视频后,该视频以正常速度播放,但其帧反复向后颤抖。


7.为什么“免费将AVCHD转换为MOV”应用程序有效?

正如我在之前的评论中提到的,将免费AVCHD转换为MOV应用程序的“重新包装为MOV”功能效果很好,即使它不是MP4而是MOV。

该软件在内部调用了自己的ffmpeg(或avconv)程序,我看到了传递给它的选项。如下图所示:

/Applications/Free AVCHD to Mov.app/Contents/Resources/bin/com.geranium-soft.convert \
  -i /path/to/140710_Canon-00003.MTS \
  -map 0:0 -map 0:1 -c:a libfaac -vol 256 -b:a 128k -c:v copy \
  -sn -movflags faststart -threads 0 -pix_fmt yuv420p -y \
  /path/to/140710_Canon-00003.mov

我尝试传递相同的选项(完全相同。我将输出容器类型设置为MOV,甚至删除了-t 60开关。)传递给ffmpeg程序并进行转换。但结果与迄今为止报道的相同

无论如何,这个出色的应用程序解决了我的问题,“在不重新编码H264视频流的情况下如何将.MTS文件(AVCHD)转换为.mp4吗?”,除了“到.mp4”和“通过ffmpeg”之外。但是我仍然对为什么该应用程序运行良好但ffmpeg不能运行感兴趣。


“正确”是什么意思?也许从标题中删除它。我想提供帮助,但是我从未使用过ffmpeg。我只是使用adobe工具的媒体编码器。
eLouai 2014年

@eLouai好吧,我确定了标题。
kaorukobo 2014年

Answers:


8

看到您的问题中已经开始讨论其他实用程序,我将假定您对坚持ffmpeg感兴趣,而对完成工作不感兴趣。

根据我对libav和MTS的经验,我对帧速率没有任何问题,文件可以完美地重新混合。

我刚尝试用我的一个文件进行以下操作:

avconv -i 00174.MTS -c:a copy -c:v copy 00174.mp4

生成的MP4文件可以在VLC中正确播放。

我的文件是渐进式MTS,我没有任何隔行扫描,但是如果需要,我可以进行更多检查。

关于文件测试的报告

主题启动程序能够提供一个文件,该文件已从MTS重定位到MP4,并且无法使用QuickTime Player在该人的计算机上播放(版本未知)。但是,它确实与该人的VLC播放器一起玩。

我没有Mac OS计算机,但已在Ubuntu上尝试过。我已经在VLC(2.0.8)和GNOME Videos(以前称为Totem)(3.8.2)的Ubuntu上播放了它;两者都发挥得很好。

然后我问了我的一个朋友,他在Mac上玩它。他在Mavericks(10.9.4)上,并且在QuickTime Player 10.3(727.4)中表现不错。

这时似乎是特定播放器有问题,或者计算机上的配置设置有问题。并且最好是尝试更新到最新版本的QTP,方法可能是先删除当前版本并完全清除旧配置。

另一种可能性

当我有一台旧机器时,我有一些高比特率文件在某些​​播放器中无法正确播放,并且它是特定于容器的。例如,VLC将拒绝播放MTS文件,它将显示一个帧,然后仅在一个半秒内显示下一个。GNOME视频播放得很好。但是当将其重新分配到MKV时,两个玩家都玩得相当好。这可能是一个类似的问题。玩家可能需要占用足够的CPU时间来读取特定的容器(在这种情况下为MP4),从而开始阻塞自己。然后,这种颠簸效应可以归因于子进程占用了CPU的资源,并且播放器非常迅速地抛弃了所有滞后的帧,然后坏的子进程再次启动,并且循环继续进行。

在这种情况下,最好的选择仍然是尝试升级软件。使用当前的多核处理器,很难在没有实际获取硬件的情况下测试对硬件升级的需求,但是也许可以查看QuickTime Player使用期间的CPU负载并将其与VLC进行比较。如果您看到100%使用QTP的任何内核,则可能表明了这一点。


avconv不太可能为他做其他工作。avconv是ffmpeg的分支,而ffmpeg会将avconv项目中的许多提交合并到ffmpeg中,而ffmpeg中可能存在类似的主要错误修复。
PTS

@ProfessorSparkles我认为它在这里起作用的事实足以使我们相信。我将等着看kaorukobo怎么说。
v010dya

@Volodya感谢您的信息。我在尝试将avconv添加到我的问题的报告。
kaorukobo 2014年

@kaorukobo“将框架反复向后颤抖”到底是什么意思?输出是否抖动或以某种方式前后跳跃?
v010dya 2014年

@Volodya我认为您的表达是正确的。眼见为实。我已将生成的Canon-00006.MTS.mp4上传到filedropper.com/canon-00006mts。 如果您不介意,请尝试使用QuickTime Player(如果您使用Mac ...)而不是VLC播放该文件。
kaorukobo 2014年

5

根据这个ffmpeg错误

隔行扫描的H.264数据包被拆分,导致MP4 STTS

当将包含隔行扫描的H.264的mpeg-ts重新混合为mp4时,每个视频帧的两个字段都被拆分为单独的数据包。诸如Mediainfo之类的软件使用STTS来确定帧速率。它将显示为50fps而不是25fps

根据规范,此处报告的帧速率失配似乎是ffmpeg混合隔行扫描MP4流的结果,根据该规范,每个字段都被分成一个数据包。因此

“使用MP4文件中的样本计数来确定帧频的软件是错误的。” 评论7

由于将字段对合并到一个访问单元中会违反MPEG-4规范,因此不会对此进行修补,因此任何执行相同操作的编码器也会这样做。

请注意,多路复用的输出,如下面的一个,发挥正常,我在Potplayer和VLC。

    ffmpeg version N-76741-g8eadabf Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)

Input #0, mpegts, from '00007.MTS':
  Duration: 00:00:07.01, start: 1.033367, bitrate: 15935 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:2[0x1200]: Subtitle: hdmv_pgs_subtitle ([144][0][0][0] / 0x0090), 1920x1080
[mp4 @ 054cf020] Codec for stream 0 does not use global headers but container format requires global headers
Output #0, mp4, to '00007.MTS.mp4':
  Metadata:
    encoder         : Lavf57.16.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 90k tbn, 90k tbc
    Stream #0:1: Audio: aac ([64][0][0][0] / 0x0040), 48000 Hz, 5.1(side), fltp, 128 kb/s
    Metadata:
      encoder         : Lavc57.15.100 aac
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (ac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[mp4 @ 054cf020] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mp4 @ 054cf020] pts has no value
    Last message repeated 209 times
frame=  420 fps=0.0 q=-1.0 Lsize=   12478kB time=00:00:07.01 bitrate=14564.2kbits/s    
video:12458kB audio:6kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.111239%
[aac @ 052fd480] Qavg: 64863.176

4

您可能想尝试使用来强制执行原始帧速率-r 29.97。FFmpeg可能出于某种原因试图调整帧速率。否则,您的语法是正确的,不应产生该错误。

关于你的第三个问题。根本不可能。使用编解码器对帧进行单独编码时,可以省略帧,但h264并非如此,但是即使使用这种编解码器,您仍然可以以某种方式修改视频流。增加帧速率也是如此,您必须添加计算出的帧或复制一些帧。

编辑:关于来自以下评论的其他信息。如果您需要更改格式标头中写入的数据而无需编写一个全新的文件,则可能需要在十六进制编辑器中进行操作。FFmpeg仅具有更改不包含流数据的元数据的选项。在文件中进行更改的方式和位置取决于容器格式。

另一个选择是将容器解复用,并将视频和音频流重新复用到指定了选项的新容器中。您可以再次指定多少取决于容器格式。在这种情况下,工具MP4Box可能会有所帮助,当您使用以下语法将原始视频流混合到新的mp4中时,可以指定帧速率:

MP4Box -add input.h264:fps=29.97 -new output.mp4

谢谢。关于-t 60切换,可以选择不指定帧率,而是指定处理时间($ ffmpeg -h|grep -- -t-> -t duration record or transcode "duration" seconds of audio/video
kaorukobo 2014年

哦,对,那是另一种编码器,对此错误表示抱歉。
PTS

参见我对答案的编辑。
PTS

再次感谢。我编辑了问题,通过尝试您的建议来添加结果。不幸的是,问题仍然存在..
kaorukobo 2014年

关于您对我的第三个问题的回答,对于我想更改视频流的帧率,而不仅仅是“值”的情况,没关系。但是,就我而言,这"set framerate/timebase values"意味着仅重写放在容器/编解码器流头上的值。为什么?有一些情况需要处理:某些编码器(例如Apple Compressor的h264转码器)向视频流注入错误的时基值(tbc),这种情况是ffmpeg注入错误的帧率/时基值,例如与原始视频文件不同。
kaorukobo 2014年

2

我知道这是一个老问题,但是它再次在Feed中弹出,因此对我来说是新问题。(-:

我看不到的一件事是现场订单。这是一个隔行扫描的文件,因此需要考虑。OP提到帧“来回颤抖”,这始终是错误字段顺序的标志。如果视频除了“颤抖”之外还可以,请尝试添加任何ffmpeg强制“首先进入顶场”,如果相反仍然不对,则相反。我对ffmpeg详细信息还不够熟悉,无法给出确切的标志。


我想尝试在您的答案上运行一些ffmepg命令。但是我的ffmpeg版本2.2.1似乎没有用于处理字段顺序的选项。我试过了,ffmpeg -h|egrep 'field|first'但是什么也没显示。ffmpeg的早期版本(0.8.6)具有-top可以处理的选项。
kaorukobo

@kaorukobo互联网提供以下功能:-vf“ fieldorder = bff”= tff,其中tb分别表示顶部和底部。的顶部= 1/0选项显然是用来改变哪些字段读取,不能写入的顺序。同样,我只是随意使用ffmpeg / avconv,所以没有保证。
Jim Mack 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.