之前写过一篇关于视频播放器的文章。播放器只简单实现了视频播放的功能,在此功能的基础上,给它加上一个视频快进的功能。

实现

添加参数

// video play control
bool do_seek = false; // 播放状态
int64_t seek_length = 5; // 快进秒数
int64_t seek_pos; // 视频跳转到的位置
int seek_dir; // 视频跳转方向(快进或者后退)
int rem_seek;

键盘监听

添加SDL键盘监听事件,通过键盘控制视频的快进后退。

...
else if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_SPACE)
thread_pause = !thread_pause;
// <- 控制后退
else if (event.key.keysym.sym == SDLK_LEFT)
{
do_seek = true;
seek_dir = 0;
}
// -> 控制快进
else if (event.key.keysym.sym == SDLK_RIGHT)
{
do_seek = true;
seek_dir = 1;
}
// q 退出播放
else if (event.key.keysym.sym == SDLK_q)
{
thread_exit = 1;
}
}
...

跳转参数获取

获取视频的时间基。根据时间基和视频实际跳转的秒数,计算出视频每次快进需要跳转的长度。

...
for (i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoindex = i;
AVRational timebase = pFormatCtx->streams[i]->time_base; // 时间基
printf("TimeBase: %d/%d\n", timebase.num, timebase.den);
rem_seek = seek_length;
seek_length *= timebase.den; // 实际跳转的长度
printf("seek length: %d\n", seek_length);
break;
}
}
...

快进

在循环中监听视频状态,当视频状态为快进时,执行视频快进或后退操作

...
if (do_seek)
{
printf("current packet pts: %d\n", packet->pts);
// 快进
if (seek_dir)
{
printf("Fast Forward %d s \n", rem_seek);
seek_pos = packet->pts + seek_length;
}
// 后退
else
{
printf("Rewind %d s \n", rem_seek);
seek_pos = packet->pts - seek_length;
}
// 视频跳转
if (av_seek_frame(pFormatCtx, videoindex, seek_pos, AVSEEK_FLAG_BACKWARD) < 0)
{
printf("Error while seeking\n");
return -1;
}
// 视频跳转状态修改
do_seek = false;
}
...

源码

https://github.com/canaconZion/streaming-practice/blob/main/ffmpeg/src/video_player.cpp

关于视频播放部分的代码,可以参考文章《基于FFMPEG+SDL的简单的视频播放器分析 》

FFMPEG+SDL简单视频播放器——视频快进的更多相关文章

  1. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  2. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  3. 音视频处理之FFmpeg+SDL+MFC视频播放器20180411

    一.FFmpeg+SDL+MFC视频播放器 1.MFC知识 1).创建MFC工程的方法 打开VC++ 文件->新建->项目->MFC应用程序 应用程序类型->基于对话框 取消勾 ...

  4. 基于<最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)>的一些个人总结

    最近因为项目接近收尾阶段,所以变的没有之前那么忙了,所以最近重新拿起了之前的一些FFMPEG和SDL的相关流媒体播放器的例子在看. 同时自己也用FFMPEG2.01,SDL2.01结合MFC以及网上罗 ...

  5. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

    转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] ...

  6. 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  7. 用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”

    FFMPEG的文档少,JavaCV的文档就更少了.从网上找到这篇100行代码实现最简单的基于FFMPEG+SDL的视频播放器.地址是http://blog.csdn.net/leixiaohua102 ...

  8. 【转】100行代码实现最简单的基于FFMPEG+SDL的视频播放器

    FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频播放器 ...

  9. FFMPEG+SDL实现视频播放器

    一. 前言 基于学习ffmpeg和sdl,写一个视频播放器是个不错的练手项目. 视频播放器的原理很多人的博客都有讲过,这里出于自己总结的目的,还是会做一些概况. 二. 视频播放器基本原理 2.1 解封 ...

  10. FFMPEG学习----使用SDL构建视频播放器

    #include <stdio.h> #include <string.h> extern "C" { #include "libavcodec/ ...

随机推荐

  1. 基于.Net Core实现的飞书文档一键导出服务(支持多系统)

    feishu-doc-export 一个支持Windows.Mac.Linux系统的飞书文档一键导出服务,仅需一行命令即可将飞书知识库的全部文档同步到本地电脑.导出速度嘎嘎快,实测700多个文档导出只 ...

  2. VSCode 编辑器的基本配置

    VSCode 编辑器的基本配置 在正式开始本文的内容之前,请允许我先做一些自我介绍: 严格来说,我是个自由职业者,经常会参与一些计算机专著的写作与翻译工作(主要作品如下图所示),业余偶尔也会有一些机会 ...

  3. Hexo博客Next主题DaoVoice实现在线联系

    注册登录DaoVoice 注册地址如下: http://www.daovoice.io/ 在官网注册帐号需要邀请码,可以输入我的邀请码 b69005f1 复制粘贴代码 修改的hexo的文件路劲如下: ...

  4. java协程线程之虚拟线程

    前言 众所周知,java 是没有协程线程的,在我们如此熟知的jdk 1.8时代,大佬们想出来的办法就是异步io,甚至用并行的stream流来实现,高并发也好,缩短事件处理时间也好:大家都在想着自己认为 ...

  5. 学习lspci:总线

    00:00.0 Host bridge 总线地址 00:00.0 是指PCI总线上的第一个设备,也称为根复杂性总线.在PCI架构中,每个设备都有唯一的总线地址,由域号.总线号.设备号和功能号组成.其中 ...

  6. netstat 某连接的 Recv-Q(接收队列)达到500多万字节的内核参数排查

    思路: cat proc文件系统下的 sys/net 目录下所有文件,根据结果降序排序(如果打印前xx,可能会漏掉关键信息,在定位问题时需要注意,慎用过滤),根据结果使用 grep -rn xxx 找 ...

  7. 2021-7-11 Vue的自定义指令简单实例

    获取焦点简单实例,用Vue.directive(ps:指令)定义,命名不要是关键字,用v-加自定义指令名称调用,而内部用钩子函数inserted来实现 <!DOCTYPE html> &l ...

  8. 2021-3-29 Enter按下事件

    先在构造器中添加keydown事件 tBoxPsw.KeyDown += TBoxPsw_KeyDown; 在事件中添加按下enter按钮所触发的方法 private void TBoxPsw_Key ...

  9. c++算法之动态规划:01背包

    什么是动态规划? 动态规划算法(dynamic programing),是一种由递推为基础的比贪心更稳定的一种优化策略,为运筹学的一部分.就是通过以递推为基础的手段非暴力求出最值. 它的总体思想其实就 ...

  10. [ABC145E] All-you-can-eat

    2023-02-25 题目 题目传送门 翻译 翻译 难度&重要性(1~10):5 题目来源 AtCoder 题目算法 背包dp 解题思路 设 \(dp_i\) 为最后一道菜在第 \(i\) 时 ...