ffmpeg protocol concat 进行ts流合并视频的时间戳计算及音画同步方式一点浅析


ffmpeg 有三种常见的视频合并方式: demuxerprotocolfilter

这里有介绍它的使用 :

http://trac.ffmpeg.org/wiki/Concatenate#demuxer

本文主要介绍ts流合并视频时候合并后视频的pkt是如何计算的,音画是怎么同步的。


这种方式 是以复制pkt的方式进行的,不需要解码,不像fitler方式合并没有编码损失。

其基本命令如下 :

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

libavformat/concat.c中会处理 -i concat:"...." 打开所有输入文件,

输出的 pkt 的 dts 和 pts 为 所有输入pkt的 dts 、 pts + 上一个 ts_offset

第一个片段的ts_offset 应该是 0 - 第一个片段的起始时间

第二个片段的ts_offset 是第一个片段中 最长流的 pts + 上一段的ts_ofsset

依此类推后面的。

main->tanscode()->transcoder_step()->process_input(): 中的这段代码 即处理了 一个片段末尾新ts_offset的计算:

    if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
!disable_discontinuity_correction) {
int64_t delta = pkt_dts - ist->next_dts;
if (is->iformat->flags & AVFMT_TS_DISCONT) {
if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
delta > 1LL*dts_delta_threshold*AV_TIME_BASE ||
pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
ifile->ts_offset -= delta;
av_log(NULL, AV_LOG_DEBUG,
"timestamp discontinuity for stream #%d:%d "
"(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n",
ist->file_index, ist->st->index, ist->st->id,
av_get_media_type_string(ist->dec_ctx->codec_type),
delta, ifile->ts_offset);
pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
if (pkt.pts != AV_NOPTS_VALUE)
pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
}

因此 其合并 方式 应该如下图所示 :

如是,生成两个测试源,验证一下 :

audio 10 video 5s 衔接测试

ffprobe -i c.mp4 -select_streams v:0 -show_packets -of json |grep pts

可以看到 pts 在 5s 处 会有一段 跳变 而 audio 在5-10s是连续的 ->

            "pts_time": "4.776667",
"pts": 432900,
"pts_time": "4.810000",
"pts": 435900,
"pts_time": "4.843333",
"pts": 438900,
"pts_time": "4.876667",
"pts": 441900,
"pts_time": "4.910000",
"pts": 444900,
"pts_time": "4.943333",
"pts": 447900,
"pts_time": "4.976667",
"pts": 450900,
"pts_time": "5.010000",
"pts": 904341,
"pts_time": "10.048233",
"pts": 907341,
"pts_time": "10.081567",
"pts": 910341,
"pts_time": "10.114900",
"pts": 913341,
"pts_time": "10.148233",
"pts": 916341,
"pts_time": "10.181567",

打开 deug_ts 在ffmeg日志处 可以看到 ts 合并方式 下一段新的 偏移 取得是audio 的长度。

audio 5s video 10s 接着音频短的片尾斜街一段

ffprobe -i c.mp4 -select_streams a:0 -show_packets -of json |grep pts

这次我们检查音频流,可以看到音频在断点处 时间戳是有跳变的。

            "pts": 657792,
"pts_time": "14.915918",
"pts": 658944,
"pts_time": "14.942041",
"pts": 660096,
"pts_time": "14.968163",
"pts": 661248,
"pts_time": "14.994286",
"pts": 882216,
"pts_time": "20.004898",
"pts": 883368,
"pts_time": "20.031020",
"pts": 884520,
"pts_time": "20.057143"

因此 基本符合开头猜想的逻辑:

小结

这种合并方式的优点是 能够 不打乱 原来每段的 音视频时间戳 进而确保音画同步,

缺点是 在音画 duration 差别过大的片段后面进行衔接 会留出一段 音或视频的空隙。 这种 空隙 播放器可能会卡最后一帧处理,不过建议是 转码处理是自行补齐静音 或视频 最后一帧。

再或者 尝试使用 ffmpeg -shortest 选项 截掉 音画 偏长的那一段内容 ,来进行 concat。

ffmpeg protocol concat 进行ts流合并视频的时间戳计算及其音画同步方式一点浅析的更多相关文章

  1. QQ视频直播架构及原理 流畅与低延迟之间做平衡 音画如何做同步?

    QQ视频直播架构及原理 - tianyu的专栏 - CSDN博客 https://blog.csdn.net/wishfly/article/details/53035342 作者:王宇(腾讯音视频高 ...

  2. 使用ffmpeg裁剪和合并视频

    剪切视频 使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存 ffmpeg -ss :: -i video.mp4 -vcodec copy -acodec copy -t :: ...

  3. 利用selenium和ffmpeg爬取m3u8 ts视频《进击的巨人》

    需求 想看下动漫<进击的巨人>,发现到处被和谐,找不到资源,但是在一个视频网站找到了在线播放,https://www.55cc.cc/dongman/17890/player-2-1.ht ...

  4. 用ffmpeg快速剪切和合并视频

    如果直接找视频剪切和合并视频的软件,通常出来的都是大的视频编辑软件或者是有图形界面的剪切软件,大型一点的功能太多安装麻烦,小型一点的功能可能不齐全. 只是简单的剪切或者一下合并一下,还是ffmpeg这 ...

  5. 使用ffmpeg合并视频文件的三种方法

    ffmpeg合并视频的方法有三种.国内大多数仅介绍了其中之一.于是觉得有必要翻译一下.其实在ffmpeg的 FAQ文档中有比较详细的说明. 使用concat协议进行视频文件的合并 这种方式的适用场景是 ...

  6. ffmpeg解析TS流

    介绍:  MPEG的系统层编码为不同的应用场景设计了两种格式:  TS(Transport Stream) 和PS(Program Stream), 它们两者之间不具有层级关系, 在逻辑上,它们两者都 ...

  7. 网络视频m3u8解密及ts文件合并

    网络视频m3u8解密及ts文件合并 参考了两篇博客: https://blog.csdn.net/weixin_41624645/article/details/95939510 https://bl ...

  8. 分析ffmpeg解析ts流信息的源码

    花费一些时间,然后全部扔了.为了不忘记和抛砖引玉,特发此贴. ffmpeg解析ts流 1.目的     打算软件方式解析出pat,pmt等码流信息 2.源代码所在位置         下载ffmpeg ...

  9. FFMPEG中关于ts流的时长估计的实现(转)

    最近在做H.265 编码,原本只是做编码器的实现,但客户项目涉及到ts的封装,搞得我不得不配合了解点ts方面的东西.下面技术文档不错,转一下. ts流中的时间估计 我们知道ts流中是没有时间信息的,我 ...

  10. 使用vlc实现视频TS流的推送

    鉴于Mpeg TS流播放的需求,使用 VLC作为Server来实现输出Mpeg TS    本文仅涉及如何使用VLC的Command来实现作为视频流Server通常可以使用下述四种方式来推送Mpeg ...

随机推荐

  1. JAVA基础Day3-用户交互Scanner/顺序结构/选择结构/循环结构

    一.用户交互Scanner JAVA提供了一个工具类,可以用来获取用户的输入. java.util.Scanner是Java5的新特征,可以通过Scanner类来获取用户的输入. 基本语法: Scan ...

  2. 在NCBI中下载SRA数据

    目前,在NCBI中下载SRA数据主要有三种方式: 利用Aspera工具下载. 利用SRA Toolkit下载. 利用wget命令直接下载 第三种最为方便.其中的关键是得到下载数据的链接,即ftp的地址 ...

  3. Markdown基础使用学习

    Mark Down学习 标题:#+标题名字 二级标题:## +标题名字 三级... 字体 两个*+字+两个=加粗 一个=斜体 引用 一个大于号+内容 图片 ![图片名字](路径) 符号全部小写 超链接 ...

  4. 微信点击链接:debugx5.qq.com提示您使用的不是x5内核

    微信点击链接:debugx5.qq.com提示您使用的不是x5内核 因为要测试小程序,需要webview调试功能,正常来说在微信任意一个聊天窗口,输入:debugx5.qq.com,点击该链接就可以, ...

  5. 互联网架构 之备份服务器 rsync

    备份服务器(Rsync) 1.介绍备份的场景 1.什么情况下需要备份 一般数据比较重要的情况下,数据如果丢失很容易找不回来了的,建议备份. 2.什么是备份 将原有的数据复制一份或几份存起来,以备不时之 ...

  6. windows 2016 安装docker

    windows 2016 安装docker 前提条件:windows server 2016安装更新 1:用管理员打开windows PowerShell Install-PackageProvide ...

  7. APK 跳转其他APK

    +import android.content.ComponentName;^M /* @@ -343,6 +346,15 @@ public class MainActivity extends A ...

  8. springboot项目导出excel实现

    参见:https://blog.csdn.net/duli_0105/article/details/102809936

  9. linux 部署轻量级堡垒机Next Terminal

    对比 类似的开源堡垒机有 Teleport,Jumpserver,Next Terminal等等. Teleport 安全性最好,较轻量,但是对被管理资产不透明,纳管前需要双向认证,在资产设备上需额外 ...

  10. Windows右键新建菜单中添加md文件

    1.win+r------->regedit 2.找到.md文件夹,双击该文件夹后修改数据的值为".md" 3.在.md文件夹右键新建"项"------& ...