获取ffmpeg转码的实时进度

简介: 获取ffmpeg转码的实时进度

前言

本文记录查看 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转码的实时进度

目录
相关文章
|
10月前
|
编解码 前端开发 Java
SpringBoot集成ffmpeg实现视频转码播放
之前构建过文件预览服务,对于视频部分前端播放组件限制只能为mp4格式,为了支持更多视频格式决定对方案进行升级,由于视频格式较多,针对每一种格式定制选择播放器不太现实,决定对视频源统一转码,转码后的格式为mp4,兼容性稳定且前后端改造工作较小
267 0
|
编解码 API 内存技术
|
编解码 前端开发
vue+ffmpeg实现前端视频转码
如何使用ffmpeg的wasm文件在浏览器实现视频转码
|
编解码 Java
JAVA调用FFMpeg进行转码等操作
JAVA调用FFMpeg进行转码等操作
275 0
|
编解码 Java Linux
Java调用ffmpeg进行视频转码
Java调用ffmpeg进行视频转码(windows或linux),以及后续的一些测试、调优
2095 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
510 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
719 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
|
编解码 Android开发 索引
【Android FFMPEG 开发】FFMPEG 视频播放进度控制 ( 显示播放进度 | 拖动进度条播放 )
【Android FFMPEG 开发】FFMPEG 视频播放进度控制 ( 显示播放进度 | 拖动进度条播放 )
546 0
|
编解码 Ubuntu
FFMPEG音频视频开发: 视频转码、合并、修改分辨率、比特率
FFMPEG音频视频开发: 视频转码、合并、修改分辨率、比特率
1172 0