如何在 h264 ffmpeg 中转换视频和音频?

如何在 h264 ffmpeg 中转换视频和音频?

ffmpeg

ffmpeg version 3.1.1 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --enable-libmfx --enable-nonfree
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

我知道使用以下命令将一种格式转换为另一种格式,

ffmpeg -i M.avi -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast M.mp4

现在我需要进行转换,例如将 M.avi 转换为 M.h264,然后从 M.h264 转换为 M.mp4

ffmpeg -i M.avi -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast M.h264

ffmpeg -i M.h264 -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast M.mp4

在执行此操作时,一切正常,但 M.mp4 播放时没有音频。

根据链接,

https://stackoverflow.com/questions/5725958/ffmpeg-conversion-skips-audio

我甚至尝试-acodec copy

ffmpeg -i M.avi -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast -acodec copy M.h264

ffmpeg -i M.h264 -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast -acodec copy M.mp4

使用该命令时ffmpeg -i M.mp4 -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast -acodec copy n.h264,结果是

ffmpeg version 3.1.1 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
  configuration: --enable-libmfx --enable-nonfree
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'M.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-01-31 09:44:22
  Duration: 00:03:28.38, start: 0.000000, bitrate: 2120 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 1925 kb/s, 24 fps, 24 tbr, 24 tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
    Metadata:
      creation_time   : 2016-01-31 09:44:23
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
File 'n.h264' already exists. Overwrite ? [y/N] y
libva info: VA-API version 0.35.0
libva info: va_getDriverName() returns 0
libva info: User requested driver 'iHD'
libva info: Trying to open /opt/intel/mediasdk/lib64/iHD_drv_video.so
libva info: Found init function __vaDriverInit_0_32
libva info: va_openDriver() returns 0
[h264 @ 0x2fd4940] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, h264, to 'n.h264':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf57.41.100
    Stream #0:0(und): Video: h264 (h264_qsv), nv12, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 1000 kb/s, 24 fps, 24 tbn, 24 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc57.48.101 h264_qsv
    Side data:
      cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: -1
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (h264_qsv))
Press [q] to stop, [?] for help
frame= 5001 fps=284 q=-0.0 Lsize=   23221kB time=00:03:28.33 bitrate= 913.1kbits/s speed=11.8x    
video:23221kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

仍然没有声音。有人能帮我解决吗?

答案1

我不知道如何通过一个步骤提取音频和视频,但您可以使用一个简短的脚本轻松提取音频和视频。

假设音频是 AAC,如您的帖子中所述:

#! /bin/bash
###################################################################
i="" # edit with the input avi file name including extension
###################################################################
  ffmpeg -i "$i" -c:v h264_qsv -look_ahead 0 -strict -2 -preset:v fast -an "${i%.*}.".h264
  ffmpeg -i "$i" -vn -acodec copy "${i%.*}.".aac
done

要将它们重新组合到 MP4 容器中,您可以执行以下操作:

#! /bin/bash
###################################################################
i="" # edit with the input h264 file name including extension
###################################################################
  ffmpeg -i "$i" -i "${i%.*}.".aac -vcodec copy -acodec copy "${i%.*}.".mp4
done

这不是一个理想的解决方案,因为它创建了一个额外的步骤(如评论中所述)。但至少它会给你一个起点:)

希望有帮助!:)

答案2

.h264 是一种原始视频容器格式。它不了解音频。ffmpeg 的行为绝对正确。如果您想要 h264 - 您可以得到它。没有音频。

答案3

正如其他人所说,没有理由分多个步骤执行此操作,并且 h264 格式无法保存音频,因此额外的步骤会导致丢失音频。

您还应该注意,您在第二步对视频进行了完全重新编码,这很浪费时间并且是有损操作(您将损失视频质量)。

要一次性转换为 h264+aac,请执行以下操作:

ffmpeg -i M.avi -c:v h264_qsv -c:a aac out.mp4

(我给出的命令是最基本的形式。您仍然应该添加额外的标志以提高质量等。)

要分多个步骤进行转换,您需要创建单独的视频和音频文件,然后将它们合并到容器中。要找出 avi 使用的是什么格式,只需运行 ffmpeg 而不使用任何标志或输出

ffmpeg -i M.avi

它将显示 avi 容器中所有频道的详细信息。

如果 avi 容器中的格式受 mp4 支持,则您可以将视频和音频拉入 mp4 而无需重新编码(这样可以避免质量损失)

ffmpeg -i M.avi -c copy M.mp4

或者你可以将它们重新编码为单独的视频和音频,然后合并

ffmpeg -i M.avi -c:v h264_qsv M.h264

ffmpeg -i M.avi -c:a aac M.aac

ffmpeg -i M.h264 -i M.aac -map 0:v -map 1:a -c copy M.mp4

请注意,您应该在最后一步复制编解码器,而不是重新编码。

相关内容