初次学习和使用ffmpeg,电脑系统有点老,没办法使用最新版的ffmpeg 3.3,只能从别处下载了一个2.8版的用用,官网提供的历史版本都没有我电脑可用的版本。

花了两天时间学习并写了一个简单的处理视频的程序,实现视频的截屏保存为jpg图片。

本来想用SDL写个播放器,但写着写着,感觉实现视频、音频同步什么的有点难,有点累,就没再继续。

今天在研究视频定位(seek)的时候,在测试代码时发现问题:

我测试了不同格式的视频: mp4,flv,mov,3gp,wmv,mkv,avi

定位,我用的是 av_seek_frame(),如果定位:wmv,avi,3gp 等,我只需简单的使用:

int64_t seekTime_us = (int64_t)8 * AV_TIME_BASE; //单位: 微秒, 必须加 (int64_t),否则有可能发生数据溢出。
av_seek_frame(pFormatCtx, -1 , seekTime_us, AVSEEK_FLAG_BACKWARD); // AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY | AVSEEK_FLAG_FRAME

结果:定位很准确。

但上面的代码用来定位:mp4,flv,mov,mkv等,经常会遇到定位不准的情况,误差在[0-5秒]左右。

在网上搜索了半天,找到下面另一种计算方法,经测试和上面的效果其实是一样的,误差在[0-5秒]左右,还不如上面的简单。

int startSecond = 8;
int64_t seekTime_us = startSecond * AV_TIME_BASE; //单位: 微秒
int64_t targetFrame = av_rescale_q(seekTime_us, AV_TIME_BASE_Q, pFormatCtx->streams[videoStream]->time_base);

int64_t seekStreamDuration = pFormatCtx->streams[videoStream]->duration;
int flags = AVSEEK_FLAG_BACKWARD; //默认使用
if(targetFrame > 0 && targetFrame < seekStreamDuration)
{
    // H.264 I frames don't always register as "keyframes" in FFmpeg
    flags |= AVSEEK_FLAG_ANY; //加了这个,有时定位更不准
}

av_seek_frame(pFormatCtx, videoStream, targetFrame, flags);
avcodec_flush_buffers(pCodecCtx);

我又换了个方式:先计算视频的总帧数(frameCount),然后通过fps计算出8秒位置的frame_index, 不用av_seek_frame,直接通过while(av_read_frame()),跳过frame_index,来实现seek,这个方法定位非常准,但不科学。因为如果要定位到60秒,我用的电脑光是花费在while(av_read_frame())上的时间就将近4秒,效率太低了,只适合定位开头几十秒内。

谁能告诉我,怎样用 av_seek_frame 来定位 mp4,flv 格式的视频精准一点,不要定位到8秒,显示的是5秒时的内容。

av_seek_frame() 定位为什么不准呢?的更多相关文章

  1. 用opencv检测人眼并定位瞳孔位置

    最近的研究要用到定位瞳孔的位置,所以上网搜了下相关的代码.总结如下: 1) 定位瞳孔可以直接使用opencv中的自带的分类器(haarcascade_eye_tree_eyeglasses.xml)来 ...

  2. PHP EXCEL相关

    这次的需求是在二次扫描的EXCEL报表中加入一列扫描时间. 扫描的时间之前已经写进日志里了,这次要做的就是把时间读取出来然后作为一列插入报表.其实日志也已经读出来了,要做的就是插入.但插入还是碰到不少 ...

  3. 通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)

    原文:通通玩blend美工(6)上--仿iPhone滚动选择器的ListBox(UI设计) 好久没更新博客了,由于项目比较紧,期间收到不少园友的短消息,感谢大家对我的支持~~. 相信各位都在自己的神机 ...

  4. datagridview 定位到最后一行,定位不准的原因

    C# 写的 winform 程序,定位到最后一行 dgvGoods.FirstDisplayedScrollingRowIndex = dgvGoods.Rows.Count - 1; 测试中发现,一 ...

  5. 百度定位api 定位不准修正

    https://www.zhihu.com/question/38313555   在安卓开发中需要设置 setCoorType("bd09lsetCoorType("bd09ll ...

  6. IE8 textarea 滚动条定位不准解决方法

    工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是j ...

  7. EasyPR--开发详解(5)颜色定位与偏斜扭转

    本篇文章介绍EasyPR里新的定位功能:颜色定位与偏斜扭正.希望这篇文档可以帮助开发者与使用者更好的理解EasyPR的设计思想. 让我们先看一下示例图片,这幅图片中的车牌通过颜色的定位法进行定位并从偏 ...

  8. IOS中GPS定位偏移纠正(适用于Google地图)

    在这个神奇的国度里,我们总得学习一些有中国特色的东东,例如“火星坐标”.也许有人还不知道这是什么玩意,我就简要介绍一下吧.      如果你有带GPS模块的智能手机,打开定位功能,然后访问Google ...

  9. html5定位并在百度地图上显示

    在开发移动端 web 或者webapp时,使用百度地图 API 的过程中,经常需要通过手机定位获取当前位置并在地图上居中显示出来,这就需要用到html5的地理定位功能. navigator.geolo ...

随机推荐

  1. ArrayList性能短板深入分析

    ArrayList的数据结构主体是Object[]数组,数组对象在内存的位置是成块成块的. 1.对数组进行非尾部修改,会引发System.arrayCopy()行为.这就需要对后半部要移动的对象进行内 ...

  2. select、poll、epoll之间的区别(搜狗面试)

    (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对 ...

  3. delphi中退出是弹出让你确定的几种确定对话框怎么写?

    procedure TForm2.btn1Click(Sender: TObject); begin if MessageBox(Handle, '你确定要退出系统吗?', '信息提示', MB_OK ...

  4. Bootstrap之信息记录

    Bootstrap中文网: http://www.bootcss.com/ 上面有一些资料和范例 实例精选: https://v3.bootcss.com/getting-started/#examp ...

  5. python安装与配置

    首先下载python地址: https://www.python.org/downloads/release/python-361/ 下载页面中有多个版本: web-based installer 是 ...

  6. opencv imdecode和imencode用法

    主要是对内存数据自动编解码 string fname = "D:/image.jpg"; //! 以二进制流方式读取图片到内存 FILE* pFile = fopen(fname. ...

  7. Windows Server 2012 Hyper-V 快照

    快照 Hyper-V 可提供擷取執行中虛擬機器快照的能力,因此可輕易地回復至前一狀態,對於測試環境相當有幫助. 快照的功用雖然很不錯,不過每次建立快照時都是會消耗相當的硬碟資源,尤其目前的快照點和上一 ...

  8. 手写事务管理器 也是spring实现事务管理的原理

  9. luogu1503

    P1503 鬼子进村 题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战. ...

  10. hdu-5536(字典树)

    题意:给你n个数,让你在n个数中选三个,使得(a1+a2)^a3的值最大,a1!=a2!=a3(下标不等于): 解题思路:01字典树可以写,因为数据小,我们可以先把n个数建一颗字典树,然后两边for找 ...