如何用FFMPEG正确将H264封装成FLV?

2024-01-12

首先,标题中的“适当”指的是这个相关问题 https://stackoverflow.com/questions/44952940/ffmpeg-how-to-wrap-h264-stream-into-flv-container,其中的答案并不能解决我的问题。

tl;dr:对视频进行编码和直接将其存储到 FLV 中以及分两个单独的步骤执行此操作之间存在差异。我需要单独执行,如何获得与直接执行相同的结果?

Nvidia 的硬件编码器 NVENC 生成没有容器的原始 H.264 数据,这很难在大多数视频播放器中播放。对于 Adob​​e AIR 应用程序,我需要将视频包装为 FLV 格式,为此我想使用 FFMPEG:

ffmpeg -f h264 -i "input.h264" -c copy -f flv "output.flv"

这没有按预期工作,因为以这种方式处理的每个视频的第一帧根本没有显示。每个视频仅从第二帧开始显示,这对于单帧视频来说是一种耻辱(仅使用 GPU 的硬件编码器进行闪电般快速的图像压缩)。

为了进行检查,我现在对输入视频重新编码两次:一次直接编码为 FLV 输出

ffmpeg -f h264 -i "input.h264" -c:v h264_nvenc -f flv "A.flv"

一次是 H.264,然后将其推入 FLV。

ffmpeg -f h264 -i "input.h264" -c:v h264_nvenc -f h264 "reencode.h264"
ffmpeg -f h264 -i "reencode.h264" -c copy -f flv "B.flv"

第一个视频播放正常,第二个则不行。直接方法生成的 FLV(A.flv,见下文)的文件结构略有不同,尤其是 NAL 单元不同,我怀疑这是不同行为的原因。

所以,我的问题是:如果我已经有一个 H.264 视频,只想将其复制到 FLV 容器中而不进行转码,但文件和帧头应该像实际转码时那样正确填写,该怎么办我把这个告诉FFMPEG?是否有用于此目的的命令,例如“-c copy butGenerateValidHeader”?

这里是文件的相关部分:

直接方法

ffmpeg -f h264 -i "input.h264" -c:v h264_nvenc -f flv "A.flv"

A.flv

46 4C 56 01 01 00 00 00 09 00 00 00 00 12 00 00 // FLV header + metadata
B8 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74
61 44 61 74 61 08 00 00 00 08 00 08 64 75 72 61
74 69 6F 6E 00 3F A0 E5 60 41 89 37 4C 00 05 77
69 64 74 68 00 40 93 80 00 00 00 00 00 00 06 68
65 69 67 68 74 00 40 8E F0 00 00 00 00 00 00 0D
76 69 64 65 6F 64 61 74 61 72 61 74 65 00 40 9E
84 80 00 00 00 00 00 09 66 72 61 6D 65 72 61 74
65 00 40 3E 00 00 00 00 00 00 00 0C 76 69 64 65
6F 63 6F 64 65 63 69 64 00 40 1C 00 00 00 00 00
00 00 07 65 6E 63 6F 64 65 72 02 00 0D 4C 61 76
66 35 37 2E 37 31 2E 31 30 30 00 08 66 69 6C 65
73 69 7A 65 00 40 F9 5C B0 00 00 00 00 00 00 09

00 00 00 C3 09 00 00 2B 00 00 00 00 00 00 00 17 // AVC sequence start
00 00 00 00
            01 4D 40 20 FF E1 00 17             // ?
                                    67 4D 40 20 // Sequence parameter set
95 A0 13 81 F7 EB 01 10 00 00 3E 80 00 0E A6 08
F1 C3 2A
         01 00 04                               // ?
                  68 EE 3C 80                   // Picture parameter set
                              00 00 00 36 09 01 // AVC NALU
94 9A 00 00 00 00 00 00 00 17 01 00 00 00
                                          00 01 // ?
94 91
      65                                        // IDR frame
        [B8 04 1D FF ...]
00 01 94 A5 09 00 00 05 00 00 00 00 00 00 00    // ?
                                             17 // AVC sequence end
02 00 00 00 00 00 00 10

先编码

ffmpeg -f h264 -i "input.h264" -c:v h264_nvenc -f h264 "reencode.h264"

重新编码.h264

00 00 00 01 67 4D 40 20 95 A0 13 81 F7 EB 01 10 // Sequence parameter set
00 00 3E 80 00 0E A6 08 F1 C3 2A
                                 00 00 00 01 68 // Picture parameter set
EE 3C 80
         00 00 00 01 65                         // IDR frame
                       [B8 04 1D FF ...]        // Frame data

挤入容器中

ffmpeg -f h264 -i "reencode.h264" -c copy -f flv "B.flv"

B.flv

46 4C 56 01 01 00 00 00 09 00 00 00 00 12 00 00 // FLV header + metadata
A4 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74
61 44 61 74 61 08 00 00 00 07 00 08 64 75 72 61
74 69 6F 6E 00 3F A4 7A E1 47 AE 14 7B 00 05 77
69 64 74 68 00 40 93 80 00 00 00 00 00 00 06 68
65 69 67 68 74 00 40 8E F0 00 00 00 00 00 00 0D
76 69 64 65 6F 64 61 74 61 72 61 74 65 00 00 00
00 00 00 00 00 00 00 0C 76 69 64 65 6F 63 6F 64
65 63 69 64 00 40 1C 00 00 00 00 00 00 00 07 65
6E 63 6F 64 65 72 02 00 0D 4C 61 76 66 35 37 2E
37 31 2E 31 30 30 00 08 66 69 6C 65 73 69 7A 65
00 40 F9 5B 40 00 00 00 00 00 00 09
                                    00 00 00 AF // AVC sequence start
09 00 00 05 00 00 00 00 00 00 00 17 00 00 00 00

00 00 00 10 09 01 94 BD 00 00 00 00 00 00 00 17 // AVC NALU
01 00 00
         00 00 00 00 01 67 4D 40 20 95 A0 13 81 // Sequence parameter set
F7 EB 01 10 00 00 3E 80 00 0E A6 08 F1 C3 2A
                                             00 // Picture parameter set
00 00 01 68 EE 3C 80
                     00 00 00 01 65             // IDR frame
                                   [B8 04 1D FF // Frame data
...]
00 01 94 C8 09 00 00 05 00 00 00 00 00 00 00    // ?
                                             17 // AVC sequence end
02 00 00 00 00 00 00 10

2017 年 8 月 8 日更新:添加了输入和输出文件以供检查

  • 输入.h264 http://drivenbynostalgia.com/files/ffmpeg/input.h264
  • ffmpeg -f h264 -i "input.h264" -c 复制 "copy.flv" http://drivenbynostalgia.com/files/ffmpeg/copy.flv
  • ffmpeg -f h264 -i "input.h264" -c:v h264_nvenc -f flv "A.flv" http://drivenbynostalgia.com/files/ffmpeg/A.flv
  • ffmpeg -f h264 -i“输入.h264”-c:v h264_nvenc -f h264“重新编码.h264” http://drivenbynostalgia.com/files/ffmpeg/reencode.h264
  • ffmpeg -f h264 -i“重新编码.h264”-c复制-f flv“B.flv” http://drivenbynostalgia.com/files/ffmpeg/B.flv
  • ffmpeg -f h264 -i“重新编码.h264”-c复制-bsf:v extract_extradata -f flv“额外数据.flv” http://drivenbynostalgia.com/files/ffmpeg/extradata.flv

(1)

“如果我已经有 H.264 视频并且只想将其复制到 FLV容器无需转码,但是文件和帧头 应按照实际转码时正确填写, 我如何将其告诉 FFMPEG?”

你要muxing:尝试以下命令(直接将 H.264 数据复制到 FLV 容器中)。

ffmpeg -i input.h264 -c:v copy output.flv

(2)

以这种方式处理的每个视频的第一帧根本不会显示。每个 视频仅从第二帧开始显示,这对于 单帧视频...

您如何检查帧以了解它只显示第 2 帧以后的帧?是AS3代码吗netStream.pause()或者通过 VLC 等媒体播放器?

在 FLV 中,每个视频帧都会进入Video Tag。对于其他编解码器,我们可以说将帧 #1 放入 videoTag #1等等..但是对于 H.264 第一个标签始终保留《AVC解码器配置" 数据,因此输入视频帧 #1 的像素将存在于 FLV 的视频标签 #2 中。
另外,在“AVC NALU”部分中,您第一个显示的字节...17 01让您知道这是一个关键帧(第一帧始终是关键帧),如果不显示第二帧(通常是 P 帧),MPEG 解码器将永远不会显示第二帧首先解码关键帧(I 帧)。你的第 1 帧图像存在于某处......

我无法使用某些时间码倒计时的 H.264 视频重现此问题。第一帧开始于00hh:00mm:00ss:00msec并且毫秒逐帧向上移动。使用第 (1) 点中所示的命令后,如果我使用,我会在 VLC 和 MPC-HC 以及 AS3 中看到第一帧appendBytes仅向解码器提供单帧数据(byteArray打包为 1 帧 FLV)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何用FFMPEG正确将H264封装成FLV? 的相关文章

  • 将网络摄像头从浏览器流式传输到 RTMP 服务器

    我正在尝试将一些内容从浏览器的网络摄像头实现流式传输到随机 RTMP 服务器 我让它工作到每 2 秒将 WEBM 我相信是 VP8 编码的电影片段发送到我的服务器的部分 但棘手的部分是从该部分将其发送到 RTMP 服务器 对 FFMPEG
  • Apple HLS 中的 PES 数据包内的访问单元如何对齐?

    Apple 是否指定了这一点 PES 数据包有效负载中应放置多少个访问单元 另外 我想知道 PES 数据包中存在哪些前缀起始代码 如果有 我认为访问单元中第一个 NAL 单元之前的单元是无用的 不能放置 正确的 我想知道它是如何在 HLS
  • FFMPEG - 连续的非单调 DTS

    我有几个需要连接的文件 有时文件工作和连接似乎没有问题 然后在其他文件上 文件不会连接 我得到 非单调 DTS 我一直在谷歌上搜索我应该对这些文件进行哪些处理 以便它们正确连接 但我仍然没有找到 有没有办法让所有文件的 DTS 完全相同 我
  • 使用 FFMPEG 的 HLS FLAC 流

    我使用以下命令从 FLAC 文件创建了一个 HLS 流 并输出 FLAC ffmpeg i 10 brass in pocket flac map 0 a c a 0 flac f hls hls playlist type vod mas
  • 有没有简单的方法来提取附件 b 格式的 h264 原始流?

    当我使用命令行使用 ffmpeg 提取视频流时 ffmpeg i 一些文件 vcodec copy an f rawvideo h264 什么 out h264 对于 Adob e Media Encoder 生成的某些媒体文件 只有 m4
  • 在 Android 4.1/4.2 设备中使用 MediaCodec.getOutputFormat() 作为编码器的问题

    我正在尝试使用 MediaCodec 将帧 通过相机或解码器 编码为视频 当通过 dequeueOutputBuffer 处理编码器输出时 我期望收到返回索引 MediaCodec INFO OUTPUT FORMAT CHANGED 因此
  • 使用 Python 从原始帧创建 MPEG4 视频文件

    我有一个原始视频帧源 我可以在 Python 中访问它 我想用它创建一个 MPEG4 视频 并带有 MP3 背景音乐 Python 中有哪些类型的工具和库可用于此类任务 最好我想要一个 API 我可以为其提供输出文件名 然后将各个帧作为 2
  • pictureBox 图片处理异常

    我最近想尝试一下锻造网 http www aforgenet com framework 因为我发现它非常简单 所以我决定使用 Video FFMPEG 命名空间进行一些简单的视频播放 这样我就可以将每个帧直接放在 pictureBox 上
  • 使用 ffmpeg 将视频与其自身连接,但相反

    我能够逆转 ffmpeg i input mp4 vf reverse output reversed mp4 我可以连接 ffmpeg i input mp4 i input mp4 filter complex 0 0 0 1 1 0
  • 如何减少 MediaCodec H264 编码器延迟

    我正在尝试使用 Android6 0 的 MediaCodec 将 h264 实时低延迟编码为流 编码器大约有 6 帧延迟 我想知道如何减少 代码来自屏幕记录 cpp https android googlesource com platf
  • 如何播放直播FLV流?

    我正在从 PC 中的网络摄像头捕获视频 并即时将其转换为 FLV 使用 ffmpeg 因此 我的 FLV 文件不断增长 现在我想以直播的形式播放它 我正在尝试 VLC 但它播放文件的时间不超过初始化时从文件读取的持续时间 我可以使用什么播放
  • 从编码视频文件中提取运动向量

    我正在尝试从编码的 mp4 文件中提取运动矢量数据 在之前的帖子中我发现 一个答案http www princeton edu jiasic cos435 motion vector c http www princeton edu jia
  • 使用 ffmpeg 提取帧的最快方法?

    您好 我需要使用 ffmpeg 从视频中提取帧 有没有比这更快的方法 ffmpeg i file mpg r 1 1 filename 03d jpg 如果 JPEG 编码步骤对性能要求太高 您可以始终将未压缩的帧存储为 BMP 图像 ff
  • 消除 ffmpeg 和 image-magic 命令中的慢速因素

    这些命令的基本思想是创建一个比较 比较定义了过去的一张 jpeg 和现在的一张 jpeg 组合起来 例如它们将相互滑动并显示前后图像 e g https media evercam io v1 cameras 1lowe scnoe com
  • MP4 到 DASH(bash 脚本)

    我有一个网站 用户可以在其中上传视频文件 我想使用 DASH 流式传输所有内容以获得自适应比特率流式传输 因此 我编写了一个 bash 脚本 由 cron 运行 将所有 mp4 文件转换为 DASH 但它无法正常工作 出了什么问题 例如 使
  • 使用 mkfifo 和传输流,这可能吗?

    我想执行一个 bash 脚本来执行以下操作 应用程序 ffmpeg 生成实时传输流 ts 文件 我需要处理这个实时流 执行解复用等 现在我知道这必须通过 FIFO 来完成 但这是我的任务 我需要重定向 ffmpeg 的输出以写入 fifo
  • 如何使用android ndk r9b为Android编译FFMPEG

    我想设计一个Android应用程序 可以通过FFMPEG命令播放和编辑视频 但我不知道如何在Android上使用FFMPEG 我尝试过从Google搜索到的许多方法 但它们太旧了 无法实现 现在 FFMPEG的最新版本是2 1 1 Andr
  • 如何从 Linux 命令行获取视频文件的分辨率(宽度和高度)?

    我一直在挖掘 mplayer mencoder 和 ffmpeg 文档 但我似乎无法想出anything 我对输出格式不是特别挑剔 因为我可以使用正则表达式将其拉出来 我只是似乎无法首先获取数据 Use ffprobe https ffmp
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • ffmpeg AVFrame 到 opencv Mat 转换

    我目前正在开发一个使用 ffmpeg 解码接收到的帧的项目 解码后 我想将 AVFrame 转换为 opencv Mat 帧 以便我可以在 imShow 函数上播放它 我拥有的是字节流 我将其读入缓冲区 解码为 AVFrame f fope

随机推荐