使用 ffmpeg 将 mkv 转换为 mp4 有时会丢失视频

Posted

技术标签:

【中文标题】使用 ffmpeg 将 mkv 转换为 mp4 有时会丢失视频【英文标题】:Converting mkv to mp4 with ffmpeg sometimes loses video 【发布时间】:2019-12-09 20:54:32 【问题描述】:

如何创建一个尽可能通用的命令行来将 mkv 转换为 mp4?

我修复了一个问题,有时我会丢失音频(我认为),现在我正在丢失视频。 这是我目前使用的命令(我使用过一些命令,包括 -analyzeduration 1G -probesize 50M,但我总是在某些时候出现损坏的视频):

if [[ $(pgrep -i ffmpeg) ]] ; then
  echo "FFMPEG IS ALREADY RUNNING!"
else 
  echo "Starting mkv to mp4 conversion...";
    for i in /var/www/html/uploads/Videos/*/*/*/*.mkv;
      do name=$(echo "$i//.mkv/");
      echo "$name";
      ffmpeg -n -i "$i" -c copy -c:a aac -movflags +faststart "$name.mp4"; rm -v -f "$name.mkv";
    done
fi

在我丢失图片的特定视频上运行的输出:

Starting mkv to mp4 conversion...
/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E02 - The Avatar Returns WEBDL-1080p
ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (GCC)
  configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-***-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzvbi --enable-avfilter --enable-avresample --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E02 - The Avatar Returns WEBDL-1080p.mkv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
  Duration: 00:23:59.11, start: 0.000000, bitrate: 1258 kb/s
    Stream #0:0(und): Video: hevc (Main 10) (hev1 / 0x31766568), yuv420p10le(tv), 1440x1080, 1124 kb/s, SAR 1:1 DAR 4:3, 23.98 fps, 23.98 tbr, 16k tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, mp4, to '/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E02 - The Avatar Returns WEBDL-1080p.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
    Stream #0:0(und): Video: hevc (Main 10) (hev1 / 0x31766568), yuv420p10le(tv), 1440x1080 [SAR 1:1 DAR 4:3], q=2-31, 1124 kb/s, 23.98 fps, 23.98 tbr, 16k tbn, 16k tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      encoder         : Lavc58.54.100 aac
[mp4 @ 0x5583e9bdb8c0] Starting second pass: moving the moov atom to the beginning of the file
frame=34504 fps=1260 q=-1.0 Lsize=  221105kB time=00:23:59.08 bitrate=1258.6kbits/s speed=52.5x
video:197477kB audio:22515kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 0.506059%
[aac @ 0x5583e9b3f140] Qavg: 562.538

编辑:

以下命令适用于上述命令没有的类似文件:

  ffmpeg -n -i "$i" -c:v libx264 -c:a aac -movflags +faststart 

输出:

Starting mkv to mp4 conversion...
/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E03 - The Southern Air Temple WEBDL-1080p
ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (GCC)
  configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-***-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzvbi --enable-avfilter --enable-avresample --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E03 - The Southern Air Temple WEBDL-1080p.mkv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
  Duration: 00:24:10.74, start: 0.000000, bitrate: 1354 kb/s
    Stream #0:0(und): Video: hevc (Main 10) (hev1 / 0x31766568), yuv420p10le(tv), 1440x1080, 1124 kb/s, SAR 1:1 DAR 4:3, 23.98 fps, 23.98 tbr, 16k tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: eac3 (ec-3 / 0x332D6365), 48000 Hz, stereo, fltp, 224 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
    Side data:
      audio service type: main
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (eac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x563ef7ad5a40] using SAR=1/1
[libx264 @ 0x563ef7ad5a40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 0x563ef7ad5a40] profile High 10, level 4.0, 4:2:0, 10-bit
[libx264 @ 0x563ef7ad5a40] 264 - core 157 r2980 34c06d1 - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=34 lookahead_threads=5 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=23 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=81 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to '/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E03 - The Southern Air Temple WEBDL-1080p.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
    Stream #0:0(und): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p10le, 1440x1080 [SAR 1:1 DAR 4:3], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      encoder         : Lavc58.54.100 aac
    Side data:
      audio service type: main
frame=   37 fps=0.0 q=0.0 size=       0kB time=00:00:02.09 bitrate=   0.2kbits/sframe=   72 fps= 72 q=0.0 size=       0kB time=00:00:03.54 bitrate=   0.1kbits/sframe=  103 fps= 68 q=40.0 size=       0kB time=00:00:04.84 bitrate=   0.1kbits/frame=  128 fps= 64 q=40.0 size=       0kB time=00:00:05.90 bitrate=   0.1kbits/frame=  169 fps= 66 q=40.0 size=     256kB time=00:00:07.59 bitrate= 276.2kbits/frame=  194 fps= 63 q=40.0 size=     512kB time=00:00:08.66 bitrate= 484.3kbits/frame=  241 fps= 68 q=40.0 size=     512kB time=00:00:10.60 bitrate= 395.6kbits/frame=  262 fps= 64 q=40.0 size=     512kB time=00:00:11.47 bitrate= 365.5kbits/frame=  284 fps= 62 q=40.0 size=     768kB time=00:00:12.37 bitrate= 508.5kbits/frame=  312 fps= 61 q=40.0 size=     768kB time=00:00:13.54 bitrate= 464.5kbits/frame=  341 fps= 61 q=40.0 size=    1024kB time=00:00:14.74 bitrate= 569.1kbits/frame=  373 fps= 61 q=40.0 size=    1280kB time=00:00:16.10 bitrate= 651.0kbits/frame=  398 fps= 60 q=40.0 size=    1280kB time=00:00:17.13 bitrate= 612.1kbits/frame=  419 fps= 59 q=40.0 size=    1536kB time=00:00:18.02 bitrate= 698.0kbits/frame=  433 fps= 56 q=40.0 size=    1792kB time=00:00:18.60 bitrate= 789.2kbits/frame=  456 fps= 55 q=40.0 size=    2048kB time=00:00:19.56 bitrate= 857.6kbits/frame=  469 fps= 53 q=40.0 size=    2304kB time=00:00:20.11 bitrate= 938.2kbits/frame=  486 fps= 52 q=40.0 size=    2816kB time=00:00:20.82 bitrate=1108.0kbits/frame=  504 fps= 51 q=40.0 size=    3328kB time=00:00:21.58 bitrate=1262.8kbits/frame=  522 fps= 51 q=40.0 size=    4096kB time=00:00:22.31 bitrate=1503.7kbits/frame=  545 fps= 50 q=40.0 size=    4608kB time=00:00:23.27 bitrate=1621.9kbits/frame=  570 fps= 50 q=40.0 size=    5120kB time=00:00:24.34 bitrate=1723.1kbits/frame=  597 fps= 50 q=40.0 size=    5632kB time=00:00:25.45 bitrate=1812.8kbits/frame=  619 fps= 50 q=40.0 size=    5888kB time=00:00:26.38 bitrate=1827.8kbits/frame=  650 fps= 50 q=40.0 size=    6400kB time=00:00:27.66 bitrate=1894.8kbits/frame=  674 fps= 50 q=40.0 size=    6656kB time=00:00:28.65 bitrate=1903.1kbits/frame=  701 fps= 50 q=40.0 size=    6656kB time=00:00:29.78 bitrate=1830.9kbits/frame=  734 fps= 51 q=40.0 size=    6912kB time=00:00:31.12 bitrate=1819.2kbits/frame=  754 fps= 50 q=40.0 size=    7168kB time=00:00:31.97 bitrate=1836.2kbits/frame=  778 fps= 50 q=40.0 size=    7168kB time=00:00:33.00 --SNIPPED--
bitrate=1518.4kbits/frame=34775 fps= 58 q=40.0 size=  268800kB time=00:24:10.64 bitrate=1518.0kbits/[mp4 @ 0x563ef7ad45c0] Starting second pass: moving the moov atom to the beginning of the file
frame=34783 fps= 58 q=-1.0 Lsize=  269967kB time=00:24:10.68 bitrate=1524.5kbits/s speed= 2.4x
video:246310kB audio:22689kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.359968%
[libx264 @ 0x563ef7ad5a40] frame I:651   Avg QP:27.80  size: 60711
[libx264 @ 0x563ef7ad5a40] frame P:10705 Avg QP:32.02  size: 14279
[libx264 @ 0x563ef7ad5a40] frame B:23427 Avg QP:37.64  size:  2554
[libx264 @ 0x563ef7ad5a40] consecutive B-frames:  6.9%  8.1%  5.5% 79.6%
[libx264 @ 0x563ef7ad5a40] mb I  I16..4: 29.6% 60.8%  9.6%
[libx264 @ 0x563ef7ad5a40] mb P  I16..4:  7.7% 10.0%  1.1%  P16..4: 20.4%  3.8%  2.2%  0.0%  0.0%    skip:54.8%
[libx264 @ 0x563ef7ad5a40] mb B  I16..4:  0.6%  0.6%  0.1%  B16..8: 13.6%  1.0%  0.2%  direct: 0.7%  skip:83.3%  L0:41.6% L1:55.3% BI: 3.1%
[libx264 @ 0x563ef7ad5a40] 8x8 transform intra:54.2% inter:75.7%
[libx264 @ 0x563ef7ad5a40] coded y,uvDC,uvAC intra: 29.1% 50.3% 11.9% inter: 3.4% 4.5% 0.1%
[libx264 @ 0x563ef7ad5a40] i16 v,h,dc,p: 25% 29%  9% 38%
[libx264 @ 0x563ef7ad5a40] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 27% 18% 25%  4%  5%  5%  5%  5%  5%
[libx264 @ 0x563ef7ad5a40] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 27% 14% 17%  7%  8%  9%  6%  7%  4%
[libx264 @ 0x563ef7ad5a40] i8c dc,h,v,p: 51% 22% 19%  9%
[libx264 @ 0x563ef7ad5a40] Weighted P-Frames: Y:2.7% UV:2.1%
[libx264 @ 0x563ef7ad5a40] ref P L0: 74.1% 16.9%  8.9%  0.1%
[libx264 @ 0x563ef7ad5a40] ref B L0: 85.8% 11.6%  2.6%
[libx264 @ 0x563ef7ad5a40] ref B L1: 96.8%  3.2%
[libx264 @ 0x563ef7ad5a40] kb/s:1390.85
[aac @ 0x563ef7ade100] Qavg: 572.905
removed '/var/www/html/uploads/Videos/TV/Avatar The Last Airbender/Season 1/Avatar The Last Airbender - S01E03 - The Southern Air Temple WEBDL-1080p.mkv'
Done transcoding!

【问题讨论】:

1) 您如何确认视频丢失或无法播放?日志表明视频已映射并且流复制到输出。 2)虽然输入扩展名是.mkv,但ffmpeg(可能正确)说它是MP4,所以一开始可能不需要重新复用。尝试将其重命名为 .mp4。 3) 音频已经是 AAC。建议添加检查以避免重新编码现有的 AAC。 1.为了检查,我只是在我的网站上打开视频并且只听到声音。 2. 只是重命名视频是以前丢失音频的原因,如果我在运行命令之前弄清楚如何检查 AAC,我可能会看到它以这种方式工作,但我不确定。 【参考方案1】:

问题

视频正在包含在您的输出中(如 ffmpeg 日志中所示),但您的浏览器不喜欢(10 位)HEVC。

解决方案

要解决此问题,您可以重新编码为 H.264、VP9、AV1 或您的浏览器支持的其他格式。或者使用browser that supports HEVC。

您可以使用ffprobe 来确定输入的格式。音频流示例:

$ ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1 input.mp4
codec_name=aac

如果您想在输出中去掉codec_name=,请使用-of default=nw=1:nk=1

这将允许您在 bash 脚本中轻松使用 if/then 语句以避免不必要的重新编码。

【讨论】:

我将更新我的脚本以测试音频/视频并使用输出来决定从那里去哪里。感谢您帮助我了解出了什么问题。 @RobertW 如果您重新编码为 H.264 并且浏览器不喜欢 10 位,则将 -vf format=yuv420p 添加到命令中。

以上是关于使用 ffmpeg 将 mkv 转换为 mp4 有时会丢失视频的主要内容,如果未能解决你的问题,请参考以下文章

批处理使用ffmpeg为mp4批量加入字幕

FFmpeg 进行不必要的复用

使用 avconv 将带字幕的 DVD 图像转换为 MKV

基于FFMPEG的封装格式转换器

将多种格式的多个文件转换为mkv

音视频处理之FFmpeg封装格式20180510