一、啰嗦几句

好几年不写博客了,一是工作计算机都加密了没法编辑提交;二是各种语言混用,什么都会就是什么都不会,delphi、c#、vb、python、c++要说我精通啥,啥也不精,所以不敢乱写。

最近做一个关于视频处理的项目,用到ffmpeg,实在是憋不住,在此记录一下摸索的过程。可以毫不夸张的说,网上关于ffmpeg的使用,大部分用命令行方式,调用api方式的很少,而且盲目抄袭甚盛,斗胆妄言,罪过罪过。

二、感谢

我是通过学习雷神的博客逐渐掌握了ffmpeg的一些东西,好歹把项目做完了,效果很好,在此向雷神由衷的表示感谢。雷神由浅入深的介绍了ffmpeg的使用方法,有理论有实践,可以说网上的很多文章很难与雷神媲美,而且国内这方面的文章太少了,这么多做视频方面的,怎么就没有这方面的优质文章,在此是个疑点。可惜的是雷神花费了大量时间开放自己的学习探索的心得,当逐步的到达核心地带时,戛然而止,雷神去世了,天妒英才呐。在此沉痛缅怀并致以崇高的敬意!

在本文中,没有直接可运行的代码,一是加密,无法拷贝;二是提倡动手实践,先把雷神的实例代码挨个学习调试,自会有极大的提高;

三、项目背景

核心一句话:接收高清视频流(H264+mp3 TS流),每30分钟存储一个mp4文件,相邻两个文件的播放要顺畅不能丢帧。为啥说是高清呢,30分钟文件就有5个G。

编程语言c++

四、踩过的坑

4.1进程方式

网上很多文章都是用命令行的,这种方式只能说测试还行,真正项目应用差点意思了,因为你要管理这个进程,他是个什么状态,你不知,但你又不能不管,关键做不到前后两个视频无缝衔接,咋整,鸡肋啊,做个测试、验证等可以,做项目不行。用api吧,资料太少,项目组意见不一,最后举个例子达成一致了,前面有个碉堡,我们明知道用手榴弹不行,还坚持让大家扔手榴弹,这是瞎耽误工夫;拿zha yao肯定行,但是有人得牺牲(扔手榴弹站在远处扔就行,zha yao包得有人扛到跟前),要想彻底解决就得用彻底的办法。所以很多时候我们缺少的就是沉下心的耐力和扛zha yao包的勇气,溃痈虽痛胜于养毒,把雷神用api的例子全部从头调试一遍,总结出流程,都需要哪些要素,时间基、采样率、音视频流是啥用来做啥,搞明白就完事了。

4.2 ffmpeg rtp

ffmpeg可以直接接收RTP,也有提供转换MP4的方法,要注意的是接收和处理放在一个线程中有问题,容易丢帧,因为UDP通信必须设置缓存大小,但是一旦处理堵住了,数据绝对会丢失。程序在现场长时间不间断运行,很难保证不出现丢帧的情况,经简单测试,直接抛弃该方式。

五、我的实现方法

1、使用UDP方式接收组播视频流,并写入文件中,文件按时间命名。

2、当检测到够30分钟时,停止写入当前文件,开始写入另一个文件。

3、通知视频转换线程,处理当前写完的文件。

4、视频转换线程,读取文件,

打开输入文件流(avformat_open_input),

创建输出上下文(avformat_alloc_output_context2),我们要根据文件转成mp4。

查找视频信息(avformat_find_stream_info),查找输入的码流:视频流、音频流、字幕流。

根据输入码流创建输出码流,流的参数拷贝就行(avcodec_parameters_copy),特别要注意的是输入输出流的时间基(time_base)。

打开输出流,写入文件头,设定一个文件结尾的阈值,当输入流剩余字节数小于该值时并且找到最后一个关键帧,则写入到输出流后,将剩余输入文件的结尾置换到下一个文件的开头中,这样前后两个文件无缝衔接,第一个文件最后一个关键帧是第二个文件开头的第一帧,所以无缝衔接了。

循环读取输入流(av_read_frame)根据流索引确定是音频还是视频流,如果是视频流写入文件的第一帧必须是关键帧。写入时特别注意音频和视频的pkt的时间(pts、dts、duration)需要根据自己的时间基重新换算(av_rescale_q_rnd),并记录第一帧的时间戳pts,换算后的pts和dts要减去第一帧的pts,这样每个文件播放就是从头开始了。写入输出流用av_interleaved_write_frame。

读取文件转换成mp4,在现场机器(高速缓存设备)上总共需要不到15秒钟。

六、最终效果

项目部署5个多月,内存(103M左右,峰值180M)、cpu(3%--8%),非常稳定,无异常崩溃退出,视频无马赛克、前后视频衔接很棒。

七、总结

坚持实践就是硬道理,无论什么职位、角色都不能眼高手低。

抄别人代码一千遍不如自己动手调一遍。

关于使用ffmpeg的一些牢骚的更多相关文章

  1. FFmpeg学习6:视音频同步

    在上一篇文章中,视频和音频是各自独立播放的,并不同步.本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的.主要有以下几个方面的内容 视音频同步的简单介绍 DTS 和 ...

  2. FFmpeg 中AVPacket的使用

    AVPacket保存的是解码前的数据,也就是压缩后的数据.该结构本身不直接包含数据,其有一个指向数据域的指针,FFmpeg中很多的数据结构都使用这种方法来管理数据. AVPacket的使用通常离不开下 ...

  3. FFmpeg + SoundTouch实现音频的变调变速

    本文使用FFmpeg + SoundTouch实现将音频解码后,进行变调变速处理,并将处理后的结果保存为WAV文件. 主要有以下内容: 实现一个FFmpeg的工具类,保存多媒体文件所需的解码信息 将解 ...

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

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

  5. ffmpeg用法及如何使用fluent-ffmpeg

    http://ffmpeg.org/ 官网 ffmpeg(命令行工具) 是一个快速的音视频转换工具. 1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an o ...

  6. FFmpeg学习4:音频格式转换

    前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...

  7. FFmpeg学习5:多线程播放视音频

    在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...

  8. FFmpeg数据结构:AVPacket解析

    本文主要从以下几个方面对AVPacket做解析: AVPacket在FFmpeg中的作用 字段说明 AVPacket中的内存管理 AVPacket相关函数的说明 结合AVPacket队列说明下AVPa ...

  9. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

随机推荐

  1. 文件上传——客户端检测绕过(JavaScript检测)(一)

    前言 通常再一个web程序中,一般会存在登陆注册功能,登陆后一般会有上传头像等功能,如果上传验证不严格就可能造成攻击者直接上传木马,进而控制整个web业务控制权.下面通过实例,如果程序只进行了客户端J ...

  2. 怎么高效学习python?其实只需要这个方法,快速掌握不叫事儿

    很多人想学python,并且希望能快速高效的学习python,但一直都没有找到合适的方法,下面谈一下我的方法. 首先,高效入门python 怎么高效学习python?想要高效,就要先搞清楚你这个阶段, ...

  3. 这本最适合夯实基础的经典 Java 书籍,可能80% 的 Java 程序员没有认真看过!

    公众号[程序员书单]出品,转载请注明出处 作者:黄小斜 今天要给大家带来的一本书,是大名鼎鼎的head first系列丛书的一本<head first Java>相信很多学习Java的朋友 ...

  4. linux基础知识点扫描

    1.tty:查看自己的虚拟终端 2.echo "你的服务器已经被我控制,请立刻打钱给我,账号12312312312314123421,否则后果自负!!!"  >  /dev/ ...

  5. H - Tempter of the Bone DFS

    小明做了一个很久很久的梦,醒来后他竟发现自己和朋友在一个摇摇欲坠的大棋盘上,他们必须得想尽一切办法逃离这里.经过长时间的打探,小明发现,自己所在的棋盘格子上有个机关,上面写着“你只有一次机会,出发后t ...

  6. C - Sweets Eating

    规律题 前缀和+规律 先求前缀和...答案为c[i]=arr[i]+c[i-m]//i>m时. #include<bits/stdc++.h> using namespace std ...

  7. Windows安装Tesseract-OCR 4.00并配置环境变量

    一.前言 Tesseract-OCR 是一款由HP实验室开发由Google维护的开源OCR(Optical Character Recognition , 光学字符识别)引擎.与Microsoft O ...

  8. PHP函数:array_chunk

    array_chunk()  -  将一个数组分割成多个. 说明: array_chunk ( array $array , int $size [, bool $preserve_keys = fa ...

  9. js输入框练习

    这个就是一个输入框的小练习(也是第一次写这个东西) <!DOCTYPE html> <html lang="en"> <head> <me ...

  10. TokenMismatchException Laravel

    随便写写:很久没写了,今天闲的. 1.错误原因:出现这个错误肯定是因为你在Laravel开启了csrf防御,但是你post提交过去的字段中没有生成_token. 2.如果你提交的字段中带有了_toke ...