前言
本文记录查看 ffmpeg 进行转码时的实时进度。所用的工程基于上个博客编译成功的工程:使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c
一、需求
使用 ffmepg 对音视频文件进行转码的时候可以看到其详细的进度。
编译源程序,原来的程序执行下面的命令:
.\ffmpeg431_test.exe - i "SampleVideo_1280x720_20mb.mp4" - vcodec libx264 - acodec copy - y SampleVideo_1280x720_20mb.flv
可以看到下面的相关信息:
但是我们看不到还有多久可以转码结束,以及当前已完成的进度为整体的多少。
二、实现获取 ffmpeg 转码的实时进度
1、思路梳理
- ffmpeg_parse_options() 函数用来实现解析参数,并且打开输入输出文件功能,当打开输入文件时就可以从其中获取到音视频总时长,因此修改其内部的 open_input_file() 函数,其内部的 avformat_open_input() 执行后可以得到输入的音视频总时长,因此我们在这里获取音视频总时长;
- transcode() 函数内部的 print_report() 函数中有实现打印当前转码的显示时间戳,因此我们在这里获取当前转码的显示时间戳;
- 将当前转码的显示时间戳除以音视频总时长即可得到 ffmpeg 转码的实时进度。
2、源码修改
将 cmdutils.c 文件中的 split_commandline 函数里面的 prepare_app_arguments(&argc, &argv);
注释掉,否则在主函数里面无论怎么传参时都会出现 argc = 1 的情况。
①、在 ffmepg.h 文件里新增两个全局变量和一个声明一个获取实时的转码进度函数
int64_t __g_total_duration; // 音视频总时长 int64_t __g_tc_cur_pts; // 当前转码的显示时间戳 double get_tc_progress(); // 获取实时的转码进度
②、在 ffmepg.c 文件中进行 获取实时的转码进度实现
// 获取实时的转码进度 double get_tc_progress() { if (__g_total_duration <= 0) return 0; printf("&&& duration=%lld, pts = %lld &&&\n", __g_total_duration, __g_tc_cur_pts); printf("***progress = %lf***\n", (double)__g_tc_cur_pts / (double)__g_total_duration); return (double)__g_tc_cur_pts / (double)__g_total_duration; }
③、在 ffmpeg_opt.c 文件中的 open_input_file 函数增加获取总时长的实现
// by lp,获取总时长,微秒转毫秒 __g_total_duration = ic->duration / 1000;
④、在 print_report 函数增加获取当前转码的显示时间戳,如果是最后一次打印报告则将音视频总时长赋值给当前转码的显示时间戳
// by lp __g_tc_cur_pts = pts / 1000; // 微秒转毫秒 if (is_last_report) { __g_tc_cur_pts = __g_total_duration; } get_tc_progress();
⑤、主函数如下
// ffmpeg431_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> extern "C" { #include "ffmpeg.h" } int main(int argc, char** argv) { //main_ffmpeg431(argc, argv); printf("hello, ffmepg4.3.1\n"); char* arrparams[9] = { 0 }; for (int k = 0; k < 9; k++) { arrparams[k] = new char[64](); } //strcpy(arrparams[0], "D:\\Project\\VS_Project\\ffmpeg431_test\\Debug\\ffmpeg431_test.exe"); strcpy(arrparams[0], "ffmpeg431_test.exe"); strcpy(arrparams[1], "-i"); strcpy(arrparams[2], "samplevideo_1280x720_20mb.mp4"); strcpy(arrparams[3], "-vcodec"); strcpy(arrparams[4], "libx264"); strcpy(arrparams[5], "-acodec"); strcpy(arrparams[6], "copy"); strcpy(arrparams[7], "-y"); strcpy(arrparams[8], "samplevideo_1280x720_20mb.flv"); main_ffmpeg431(9, arrparams); for (int k = 0; k < 9; k++) { delete[] arrparams[k]; } //avgeneralmediainfo* avmi = new avgeneralmediainfo(); //if (avmi) { // get_avgeneral_mediainfo(avmi, "samplevideo_1280x720_20mb.mp4"); // delete avmi; // avmi = null; //} }
三、运行结果
可以看到我们新增的打印信息,并且可以看到转换的进度
最后一次转换后的进度为 1,即 100%,完成了转码
四、资源获取
下载链接:获取ffmpeg转码的实时进度