`
yang_danny
  • 浏览: 5949 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

解密FFmpeg播放track mode控制

阅读更多

上一篇文章我们解决了在FFmpeg下如何处理H264AAC的扩展数据,根据解出的NALU长度恢复了H264的起始码和AACADTS头,这样一般来说播放是没有问题。本篇文章来谈谈如何实现基于FFmpegtrack mode控制,也就是如何用FFmpeg提供的功能来实现基本的seek、快进、快退。好了,废话少了,下面开始基于FFmpegtrack 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为单位。

Flagsseek标志,可以设置为按字节,在按时间seek时取该点之前还是之后的关键帧,以及不按关键帧seek等,详细请参考FFmpegavformat.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_scaletime_base都能通过流信息获取到,请参考前面的文章。有的文件不一定能seek成功,可以考虑在失败的情况下将AVSEEK_FLAG_BACKWARD改为AVSEEK_FLAG_ANY再次seek,不过seek到的视频帧可能不是I帧。

这个函数不管你当前在什么时间点上,都可以seek到任何合理位置。比如要实现在当前的基础上向后或向前跳转10秒,我们可以在av_read_frame函数拿到的包中含有当前时间戳的基础上增加或较少一个10000(换算成播放时间单位)再seek即可。所以这个函数可以用做进度的拖放、前进/后退一定时间、循环播放等功能。

  1. 快进快退

对于快进来说,一般解码器能实现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即可关注,里面有大量AndroidChromiumLinux,编程技巧等相关文章等着您,我们还可以在线交流。

如需转载本文,请注明出处

谢谢合作!

 

分享到:
评论

相关推荐

    qt+ffmpeg播放音频

    在本文中,我们将深入探讨如何使用Qt和FFmpeg库来实现音频播放功能。Qt是一个流行的C++图形用户界面工具包,而FFmpeg则是一个强大的多媒体处理框架,支持各种音视频编码、解码以及流处理。将这两者结合,我们可以...

    C# ffmpeg 处理视频、C# ffmpeg播放视频

    在播放视频方面,C#可以借助于DirectShow或Windows Media Foundation框架,但结合FFmpeg,可以实现更底层的控制和定制化。使用FFmpeg播放视频通常涉及到解码和渲染两个部分。解码过程如上所述,而渲染则可能需要对...

    android ffmpeg rtsp播放

    在Android平台上实现FFmpeg RTSP播放涉及多个技术层面,包括FFmpeg库的移植、Android多媒体框架的理解以及网络流媒体协议的处理。以下是对这个主题的详细解析: **FFmpeg库移植** FFmpeg是一个开源的多媒体处理框架...

    QT+ffmpeg播放视频

    QT+ffmpeg播放视频是将两种强大的工具结合,用于在Qt应用程序中实现高效的视频播放功能。Qt是一个跨平台的C++图形用户界面库,而ffmpeg是一个开源的多媒体处理框架,广泛应用于视频播放、转换和流媒体服务。下面我们...

    QT FFMPEG播放H264

    接下来,创建一个视图组件(如QVideoWidget)用于显示视频,并创建一个QMediaPlayer对象来控制播放。然后,我们需要一个QMediaContent对象来承载我们的H264视频数据。由于FFmpeg可以直接读取H264流,我们可以创建一...

    QT + ffmpeg 播放 rtsp,rtmp,udp视频流

    10. **事件处理和播放控制**:实现播放、暂停、停止、快进、快退等控制功能,这通常涉及处理QT的信号和槽。 11. **关闭流和清理**:在播放结束时,记得关闭流、解码器上下文和释放相关资源。 以上就是使用QT + ...

    MP3播放器(利用ffmpeg库,可以播放mp3,wma)

    MP3播放器是一种常见的音频播放软件,而这个项目利用了著名的开源库——FFmpeg,使得播放器能够支持MP3和WMA格式的音频文件。FFmpeg是一个强大的多媒体处理框架,包含了许多子模块,如音视频编码解码器、格式转换...

    FFmpeg-master.zip_FFmpeg-master_ffmpeg_ffmpeg 播放

    "FFmpeg-master.zip" 是 FFmpeg 源代码的压缩包,"FFmpeg-master" 是源代码仓库的主目录,而 "ffmpeg_ffmpeg 播放" 指的是使用 FFmpeg 进行视频播放的相关示例。 在 FFmpeg 中,播放视频主要涉及到以下几个关键步骤...

    FFmpeg解码MP4分别播放YUV视频和PCM音频

    在本文中,我们将深入探讨如何使用FFmpeg解码MP4文件,并分别播放其中的YUV视频和PCM音频。 MP4是一种广泛应用的多媒体容器格式,它可以包含多种音视频编码的数据。FFmpeg支持对MP4格式的文件进行解码,提取出原始...

    FFMPEG Qt视频播放器之播放控制

    从零开始学习音视频编程技术(十) FFMPEG Qt视频播放器之播放控制 FFMPEG的版本是2.5.2 SDL的版本是2.04 记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。 关于代码的解释 请...

    demo4.rar:《第4课 FFmpeg播放本地mp4文件》对应源文件

    要显示视频画面,就要先用FFmpeg读取本地mp4文件,mp4...与处理rtmp流类似,要播放音频,同样要用FFmpeg对mp4文件中的音频流进行解码获取到音频帧,然后将音频帧数据喂给由Windows系统声音播放API构成的函数就可以了。

    C++基于FFmpeg的音频解码和播放

    通过理解这个流程,你可以根据自己的需求扩展或优化这个基础播放器,例如添加文件选择对话框、支持更多音频格式、控制播放进度等。FFmpeg的灵活性和强大功能使得它成为音视频处理领域的首选库之一。

    ffmpeg播放视频

    ffmpeg播放视频,但是还不支持声音,播放速度稍快。

    VC下利用ffmpeg解码播放视频,播放上一帧,下一帧,保存为图片

    偶然发现VC下使用ffmpeg解码的资料很少,该工程可实现播放VC下利用ffmpeg解码播放视频,播放上一帧,下一帧,并把每帧保存为图片功能,因为项目最终没有应用上,所以没有完善代码,但大家可以根据自己的需要去修改、...

    ffmpeg播放hls视频流程代码走读

    ffmpeg播放m3u8网络视频文件的流程,详细描述了整个播放过程的代码流程。

    C#开发FFMPEG例子(API方式) FFmpeg拉取RTMP流并播放原始源码

    在C#中使用FFmpeg API进行开发,可以实现对多媒体数据的高效处理,例如拉取RTMP流并播放。下面将详细介绍如何在C#中使用FFmpeg API来实现这个功能。 首先,你需要在项目中引入FFmpeg的C#绑定库,这通常通过NuGet包...

    网络接收H264视频数据并通过FFmpeg实时播放视频

    FFmpegAndroid-master包含无线网接收H264视频数据,将数据以队列的时候接收下来,每个队列节点是10K,接收并实时通过FFmpeg解析,再画图播放,同时包含日志调试部分,将日志以文件的形式保存在设备内,USB部分需要...

    iOS FFmpeg播放RTSP流的Demo

    它允许客户端与服务器进行交互,请求媒体数据的特定部分,并控制播放速度等。在iOS应用中播放RTSP流,我们需要一个能解析和处理这种协议的库,FFmpeg恰好提供了这样的能力。 接下来,我们来看看FFmpeg编译的过程。...

    基于ffmpeg解码播放rtsp视频流的Delphi源码

    6. **控制**:提供播放、暂停、停止等用户交互功能,通过调用FFmpeg的相关API实现。 由于描述中提到此播放器目前仅支持视频解码,音频部分尚未实现,因此在实际应用中可能需要进一步扩展以包含音频解码和同步播放。...

Global site tag (gtag.js) - Google Analytics