上一篇文章(http://my.oschina.net/u/2336532/blog/400790)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H264的起始码和AAC的ADTS头,这样一般来说播放是没有问题。本篇文章来谈谈如何实现基于FFmpeg的track mode控制,也就是如何用FFmpeg提供的功能来实现基本的seek、快进、快退。好了,废话少了,下面开始基于FFmpeg的track mode之旅。
FFmpeg提供了一个seek函数,原型如下:
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
参数说明:
s:操作上下文;
stream_index:基本流索引,表示当前的seek是针对哪个基本流,比如视频或者音频等等。
timestamp:要seek的时间点,以time_base或者AV_TIME_BASE为单位。
Flags:seek标志,可以设置为按字节,在按时间seek时取该点之前还是之后的关键帧,以及不按关键帧seek等,详细请参考FFmpeg的avformat.h说明。基于FFmpeg的所有track mode几乎都是用这个函数来直接或间接实现的。
-
文件的seek功能实现
要转跳到视频100秒(100 000毫秒)处的第一个I帧(如果没有则向前找第一个):
av_seek_frame(pFormatCtx, vid_index, 100000*vid_time_scale/time_base, AVSEEK_FLAG_BACKWARD);
跳到音频80秒(80 000毫秒)处的帧(采样):
av_seek_frame(pFormatCtx, aud_index, 80000*aud_time_scale/ time_base, AVSEEK_FLAG_BACKWARD);
跳到文件开始的地方开始播放:
av_seek_frame(pFormatCtx, vid_index, 0, AVSEEK_FLAG_BACKWARD);
上面的time_scale、time_base都能通过流信息获取到,请参考前面的文章。有的文件不一定能seek成功,可以考虑在失败的情况下将AVSEEK_FLAG_BACKWARD改为AVSEEK_FLAG_ANY再次seek,不过seek到的视频帧可能不是I帧。
这个函数不管你当前在什么时间点上,都可以seek到任何合理位置。比如要实现在当前的基础上向后或向前跳转10秒,我们可以在av_read_frame函数拿到的包中含有当前时间戳的基础上增加或较少一个10000(换算成播放时间单位)再seek即可。所以这个函数可以用做进度的拖放、前进/后退一定时间、循环播放等功能。
-
快进快退
对于快进来说,一般解码器能实现2倍甚至再高倍速的播放,这种情况直接按照上一篇文章的基本播放流程就可以了。但对于4倍、8倍、16倍、32倍等高速播放,一般不能像传统播放那样一帧一帧的送数据,不只是解码能力问题,数据读取也可能因为带宽不够跟不上,我们只能提取其中的I帧进行播放,将B帧和P帧丢掉。下面我们就来讨论这个过程的实现流程。
快进时,通过当前数据包获得当前的时间PTS,将该PTS换算成时间再加上一小段时间,作为seek时间点向后找关键帧,此时flags可设置为AVSEEK_FLAG_FRAME。之后用av_read_frame获取到该关键帧。完成该帧解码显示后,再在该帧的PTS时间上增加一小段时间后seek,这样一直重复上述过程,流程如下图:
快退时,通过当前数据包获得当前的时间PTS,将该PTS换算成时间再减去一小段时间,作为seek时间点向前找关键帧,此时flags可设置为AVSEEK_FLAG_BACKWARD。之后用av_read_frame获取到该关键帧。完成该帧解码显示后,再在该帧的PTS时间上减去一小段时间后seek,这样一直重复上述结果,过程如下图:
这样,我们通过以上对av_seek_frame函数的运用,即可完成文件playback的各种track mode实现,其实理解了这个函数后,你还会有很多其他办法来实现,这里只是提供了一种简单且占内存少的办法。在特定的情况下还可以先全部走一遍所有帧,并记录下全部的I帧的时间戳、帧编号、位置信息等需要的信息,然后直接从该表里面获取信息后进行seek和读取这些关键帧进行快速播放。
想第一时间获得更多原创文章,请关注个人微信公众平台:程序员互动联盟(coder_online),扫一扫下方二维码或者搜索微信号coder_online即可关注,里面有大量Android,Chromium,Linux,编程技巧等相关文章等着您,我们还可以在线交流。
如需转载本文,请注明出处:http://my.oschina.net/u/2336532。
谢谢合作!
相关推荐
在本文中,我们将深入探讨如何使用Qt和FFmpeg库来实现音频播放功能。Qt是一个流行的C++图形用户界面工具包,而FFmpeg则是一个强大的多媒体处理框架,支持各种音视频编码、解码以及流处理。将这两者结合,我们可以...
在播放视频方面,C#可以借助于DirectShow或Windows Media Foundation框架,但结合FFmpeg,可以实现更底层的控制和定制化。使用FFmpeg播放视频通常涉及到解码和渲染两个部分。解码过程如上所述,而渲染则可能需要对...
在Android平台上实现FFmpeg RTSP播放涉及多个技术层面,包括FFmpeg库的移植、Android多媒体框架的理解以及网络流媒体协议的处理。以下是对这个主题的详细解析: **FFmpeg库移植** FFmpeg是一个开源的多媒体处理框架...
QT+ffmpeg播放视频是将两种强大的工具结合,用于在Qt应用程序中实现高效的视频播放功能。Qt是一个跨平台的C++图形用户界面库,而ffmpeg是一个开源的多媒体处理框架,广泛应用于视频播放、转换和流媒体服务。下面我们...
接下来,创建一个视图组件(如QVideoWidget)用于显示视频,并创建一个QMediaPlayer对象来控制播放。然后,我们需要一个QMediaContent对象来承载我们的H264视频数据。由于FFmpeg可以直接读取H264流,我们可以创建一...
10. **事件处理和播放控制**:实现播放、暂停、停止、快进、快退等控制功能,这通常涉及处理QT的信号和槽。 11. **关闭流和清理**:在播放结束时,记得关闭流、解码器上下文和释放相关资源。 以上就是使用QT + ...
MP3播放器是一种常见的音频播放软件,而这个项目利用了著名的开源库——FFmpeg,使得播放器能够支持MP3和WMA格式的音频文件。FFmpeg是一个强大的多媒体处理框架,包含了许多子模块,如音视频编码解码器、格式转换...
"FFmpeg-master.zip" 是 FFmpeg 源代码的压缩包,"FFmpeg-master" 是源代码仓库的主目录,而 "ffmpeg_ffmpeg 播放" 指的是使用 FFmpeg 进行视频播放的相关示例。 在 FFmpeg 中,播放视频主要涉及到以下几个关键步骤...
在本文中,我们将深入探讨如何使用FFmpeg解码MP4文件,并分别播放其中的YUV视频和PCM音频。 MP4是一种广泛应用的多媒体容器格式,它可以包含多种音视频编码的数据。FFmpeg支持对MP4格式的文件进行解码,提取出原始...
从零开始学习音视频编程技术(十) FFMPEG Qt视频播放器之播放控制 FFMPEG的版本是2.5.2 SDL的版本是2.04 记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。 关于代码的解释 请...
要显示视频画面,就要先用FFmpeg读取本地mp4文件,mp4...与处理rtmp流类似,要播放音频,同样要用FFmpeg对mp4文件中的音频流进行解码获取到音频帧,然后将音频帧数据喂给由Windows系统声音播放API构成的函数就可以了。
通过理解这个流程,你可以根据自己的需求扩展或优化这个基础播放器,例如添加文件选择对话框、支持更多音频格式、控制播放进度等。FFmpeg的灵活性和强大功能使得它成为音视频处理领域的首选库之一。
ffmpeg播放视频,但是还不支持声音,播放速度稍快。
偶然发现VC下使用ffmpeg解码的资料很少,该工程可实现播放VC下利用ffmpeg解码播放视频,播放上一帧,下一帧,并把每帧保存为图片功能,因为项目最终没有应用上,所以没有完善代码,但大家可以根据自己的需要去修改、...
ffmpeg播放m3u8网络视频文件的流程,详细描述了整个播放过程的代码流程。
在C#中使用FFmpeg API进行开发,可以实现对多媒体数据的高效处理,例如拉取RTMP流并播放。下面将详细介绍如何在C#中使用FFmpeg API来实现这个功能。 首先,你需要在项目中引入FFmpeg的C#绑定库,这通常通过NuGet包...
FFmpegAndroid-master包含无线网接收H264视频数据,将数据以队列的时候接收下来,每个队列节点是10K,接收并实时通过FFmpeg解析,再画图播放,同时包含日志调试部分,将日志以文件的形式保存在设备内,USB部分需要...
它允许客户端与服务器进行交互,请求媒体数据的特定部分,并控制播放速度等。在iOS应用中播放RTSP流,我们需要一个能解析和处理这种协议的库,FFmpeg恰好提供了这样的能力。 接下来,我们来看看FFmpeg编译的过程。...
6. **控制**:提供播放、暂停、停止等用户交互功能,通过调用FFmpeg的相关API实现。 由于描述中提到此播放器目前仅支持视频解码,音频部分尚未实现,因此在实际应用中可能需要进一步扩展以包含音频解码和同步播放。...