【问题标题】:Cannot Play Video Output of Libavcodec (ffmpeg) Encoding Example无法播放 Libavcodec (ffmpeg) 编码示例的视频输出
【发布时间】:2019-04-19 02:47:12
【问题描述】:

来自 FFMPEG 的 GitHub,我使用 encode_video.c 生成 1 秒视频。这是有问题的示例:https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/encode_video.c

我编译:gcc -Wall -o ffencode encode_video.c -lavcodec -lavutil -lz -lm

干净编译,零警告。

我通过运行测试程序:./ffencode video.mp4 libx264

打印出大量统计信息(预计基于源代码)以及 ffmpeg 日志,但最终没有错误或警告。

但是,生成的输出video.mp4,只能由ffplay播放,VLC Player(以及谷歌浏览器)无法播放视频。

通过vlc 命令行播放它实际上会打印:

[00007ffd3550fec0] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
TagLib: MP4: Invalid atom size
TagLib: MP4: Invalid atom size
TagLib: MP4: Invalid atom size

查看ffprobe 输出,比特率和持续时间字段为空:

Input #0, h264, from 'video.mp4':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 352x288, 25 fps, 25 tbr, 1200k tbn, 50 tbc

我正在使用具有以下配置的 ffmpeg 4.1:

ffprobe version 4.1 Copyright (c) 2007-2018 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-opencl --enable-videotoolbox
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100

任何想法如何解决这个问题?看到 API 的官方示例缺少这样的基本信息,真是令人惊讶。

【问题讨论】:

    标签: c video ffmpeg video-encoding libavcodec


    【解决方案1】:

    该示例生成原始比特流 - 它不是 MP4。该示例仅用于演示编码,而不是复用(将一个或多个流打包成 MP4 等容器文件格式的术语)。

    将扩展名重命名为 .h264 并使用 VLC 进行测试。不知道 Chrome 是否支持原始 .h264 文件。

    要从此输出生成 MP4,请运行

    ffmpeg -i video.mp4 -c copy actually.mp4
    

    【讨论】:

    • 也许我应该澄清更多 - 我正在寻找一种通过 libavcodec (即 C 程序)实现这一目标的方法。基本上我想知道示例代码缺少什么。相对而言,使用ffmpeg CLI 进行编码是微不足道的。
    • 我的 ffmpeg 命令没有编码——它是复用的。请参阅github.com/FFmpeg/FFmpeg/blob/master/doc/examples/muxing.c,它会在之后进行编码和复用。
    • 从来没有说过你的命令是编码的。我是说如果我想使用 CLI 来解决这个问题,我也会以这种方式进行编码。如果需要更多说明:encode_video.c 示例缺少使视频可播放的内容。我在 libavcodec 中寻找那个“东西”。
    • 视频可播放 - libavcodec 只能编码,因此它会生成原始比特流,因此如果编码器是 libx264,则需要为输出提供 h264 的扩展名。 MP4 是一个容器,需要通过 libavformat 进行复用。 ffplay 不太关心输入扩展。 VLC 出人意料地做到了。
    【解决方案2】:

    您需要将视频流混合到视频容器中,例如.mp4。复用的东西保存在 libavformat 中。算法应该是这样的:

    • 通过调用av_register_all 或手动注册感兴趣的格式来初始化格式库。
    • 通过调用avformat_alloc_context 创建复用上下文
    • 通过调用avformat_new_stream 创建一个或多个媒体流
    • 通过调用avformat_write_header 写入标题
    • 通过调用av_write_frame写入媒体数据
    • 通过调用av_write_trailer 编写预告片
    • 通过调用avformat_free_context 销毁复用上下文

    【讨论】:

      【解决方案3】:

      只能通过 ffplay 播放,VLC Player(以及谷歌浏览器)无法播放视频。 由于 ffplay 能够播放视频,其他媒体播放器也可以播放。您需要配置 vlc 来读取 X264 编码的视频。转到首选项全选并将解复用器更改为视频 H264

      【讨论】:

        猜你喜欢
        • 2013-12-14
        • 2018-01-09
        • 2016-06-08
        • 2020-12-24
        • 2019-04-07
        • 2019-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多