一、前言
ffprobe.exe是ffmpeg自带可执行程序,ffmpeg是很强大的多媒体框架,包含了解码、编码、转码、解码、混合、流媒体等等众多能多功能。
ffmpeg不仅有开源的源代码,支持代码完成各种音视频操作,也提供了命令行的操作。ffmpeg提供的ffmpeg.exe可执行文件的功能已经可以满足很多基本的音视频处理,比如: 视频剪切、视频转码、视频收流、视频录制、视频推流、视频合并,视频转流、等等。
除了ffmpeg.exe之外,还有ffprobe.exe,可以获取媒体文件的详细信息。如果想要查看媒体文件的编码、总时长、分辨率、声道、比特率、帧率、制作者等等信息,就可以通过ffprobe.exe来得到。
ffprobe.exe -i <视频的名称>
这篇文章就介绍QT里如何采用QProcess调用ffprobe命令完成输出信息获取,分析,实现完整的功能开发。
Qt的QProcess类用于启动外部程序,并与其通信,功能比较强大。
使用QProcess类调用ffmpeg、ffprobe一般有两种需求模式:
- 只是为了完成特定功能,比如: 完成视频转码、剪切、推流,获取视频详细信息等。这种情况可以采用阻塞模式,直接放在子线程里执行,阻塞等待执行完毕。
- 在转码、录制、等过程中为了得到ffmpeg的进度,完成中途正常退出,能正常保存视频,那么就需要实时与ffmpeg交互。
二、案例代码: 获取视频的总时间
下面的这个例子采用QProcess调用ffprobe.exe获取视频的总时长。
命令格式如下:
ffprobe.exe -i D:/123.mp4
输出的信息字段:
C:\Users\11266>ffprobe.exe -i D:/123.mp4
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20200122
configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'D:/123.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2015-04-30T02:43:22.000000Z
Duration: 00:01:33.90, start: 0.000000, bitrate: 715 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 88200 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
creation_time : 2015-04-30T02:43:22.000000Z
handler_name : GPAC ISO Audio Handler
Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 582 kb/s, 15 fps, 25 tbr, 30k tbn, 20000k tbc (default)
Metadata:
creation_time : 2015-04-30T02:43:23.000000Z
handler_name : GPAC ISO Video Handler
里面有一个Duration
字段,存放的是视频总时间。
代码实现如下:
/*
功能: 获取视频总时间
*/
qint64 Widget::GetVideo_TotalTime(QString video_name)
{
QString cmd=QString("%1 -i \"%2\"").arg(ffprobe_name).arg(video_name);
qDebug()<<"cmd:"<<cmd;
qDebug()<<"当前路径:"<<QCoreApplication::applicationDirPath();
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
process.start(cmd);
process.waitForFinished();
process.waitForReadyRead();
QString qba = process.readAll();
char *find_p=strstr(qba.toUtf8().data()," Duration:");
if(find_p)
{
find_p+=11;
QString find_str=find_p;
find_str=find_str.section(',', 0, 0);
qDebug()<<"视频总时间:"<<find_str;
QTime time=QTime::fromString(find_str);
//qDebug()<<"时:"<<time.hour();
//qDebug()<<"分:"<<time.minute();
//qDebug()<<"秒:"<<time.second();
//qDebug()<<"毫秒:"<<time.msec();
//视频总时间
video_time_lent=time.hour()*60*60*1000+time.minute()*60*1000+time.second()*1000+time.msec();
}
return 0;
}