Ununtu16.04系统下编译安装ffmpeg、抽帧和计算图片时间点

ffmpeg是开源的、功能强大的视频、音频、图像处理工具,在最近的工作中,需要从视频中抽取图像,并准确计算每张图片对应在视频播放中的时间点。在网上找了一圈发现,所有的参考资料基本分为两种:

1、通过c语言调用ffmpeg进行抽帧,无奈技术太渣,此路不通

2、通过ffmpeg命令进行抽帧,这种方式无论抽取关键帧还是按照时间间隔(隔 N 秒抽一帧)抽帧都很方便,速度也快

但是找了一圈就是没有如何计算图像在视频中时间点的方法,今天在此对于如何使用ffmpeg命令抽帧(关键帧、时间间隔抽帧),以及如何计算图片时间点做一个详细的总结。


  • 安装ffmpeg

抽帧第一步,安装ffmpeg。下面介绍在Ununtu 16.04系统上快速安装ffmpeg工具的方法:

1、下载 yasm-1.3.0.tar.gz 和 ffmpeg-4.0.2.tar.bz2 压缩包,下载地址 https://download.csdn.net/download/cxx654/10762083

2、在压缩包的同一目录下创建 install_ffmpeg.sh 脚本文件,脚本功能是解压压缩包并进行编译安装,脚本执行约15分钟,执行完成后使用 ffmpeg -version 检查是否安装成功

  1.     #!/bin/bash
    
    	current_path=$(`dirname $0`;pwd)
    	cd $current_path
    
    	# install yasm
    	tar xvf yasm-1.3.0.tar.gz
    	cd yasm-1.3.0
    	./configure && make && make install
    
    	# install ffmpeg
    	cd ..
    	tar jxvf ffmpeg-4.0.2.tar.bz2
    	cd ffmpeg-4.0.2
    	./configure --prefix=/usr/local/ffmpeg
    	make && make install
    
    	# 添加环境变量
    	sed -i '$a PATH=$PATH:/usr/local/ffmpeg/bin' ~/.bashrc
    	sed -i '$a export PATH' ~/.bashrc
    
    	source ~/.bashrc   # 设置生效
    	# ffmpeg -version     # 查看版本

     


  • 抽取关键帧和时间点计算

1、关键帧抽帧命令:ffmpeg -i xxx.mp4 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 2 image/%09d.jpg -loglevel debug 2>&1 | grep -i "pict_type:I" | awk -F" " '{print $6}'| awk -F":" '{print $2}' > image/temp.txt (备注:抽取视频xxx.mp4的关键帧放在当前目录的image文件夹中,图片编号长度为9位数字, -loglevel debug设置是输出抽帧日志,并过滤pict_type:I关键帧信息保存到image目录的temp.txt 文件中)

2、经过步骤1处理后,image目录下保存有抽帧的结果图片,并且temp.txt文件中保存每个图像对应的时间点,一一对应,内容如下:

            240.000000
            241.600000
            244.000000
            246.400000
            nan
            251.200000
            253.240000
            255.000000
            257.160000

3、由于ffmpeg日志打印存在问题,导致temp.txt文件中丢失了部分时间点(如上述的nan),约占总数的1%,对于这个问题暂时没找到解决方法,可以采用上一帧的时间点代替


  • 时间间隔抽帧和时间点计算

    方法一:

1、按照时间间隔抽帧命令:ffmpeg -i xxx.mp4 -vf fps=1/4 image/%09d.jpg,使用该命令对xxx.mp4文件抽帧,抽帧间隔为4秒,如果想每秒抽取多帧,可以使用命令:ffmpeg -i xxx.mp4 -vf fps=2 image/%09d.jpg(每秒抽2帧)

2、抽帧时间点计算

对于按照时间间隔抽帧的时间点计算,直观上理解通过图片 编号 * 时间间隔 就可以计算,但是实践发现,ffmpeg按照时间间隔抽帧,抽取的第一张图片对应的时间与抽帧间隔有关,总结规律如下:

                process_offset = {
                    "1" : 0, "2" : 0,
                    "3" : 1, "4" : 1,
                    "5" : 2, "6" : 2,
                    "7" : 3, "8" : 3,
                    "9" : 4, "10" : 4
                }

即:当抽帧间隔为1秒、2秒时,第一张图片对应的时间点为第0秒;当抽帧间隔为3秒、4秒时,第一张图片对应的时间点位第1秒;依次类推。因此,在上述第一张图片存在时间偏移的基础上,计算每张图片的时间点公式如下:
            seconds = (image_count - 1) * SPEED + process_offset[SPEED],其中SPEED为抽帧速度,image_count为图片编号(从1开始)

    方法二:

1、获取视频的time_base
        ffprobe -v quiet -show_streams -select_streams v -i xxx.mp4 | grep time_base= | grep time_base | grep -v codec | awk -F"/" '{print $2}'

2、按照时间间隔抽帧,并获取每张图片的pts时间
        ffmpeg -i xxx.mp4 -f image2 -vf fps=fps=1/4 image/%09d.jpg -loglevel debug 2>&1 | grep 'Read frame with' | grep -v 'out pts 0' | grep -v 'd=' | awk -F" " '{print $9}' | sort -t ',' -k 2,2 -u | awk -F"," '{print $1}' > temp.txt

3、计算图片时间点(秒)

使用第二步产生的每个pts值除以第一步得到的 time_base,就是每张图片对应的时间点

参考:https://blog.csdn.net/qingyuanluofeng/article/details/45397811

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章