QProcess调用ffprobe.exe获取视频总时间

999 阅读3分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

一、前言

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一般有两种需求模式:

  1. 只是为了完成特定功能,比如: 完成视频转码、剪切、推流,获取视频详细信息等。这种情况可以采用阻塞模式,直接放在子线程里执行,阻塞等待执行完毕。

  2. 在转码、录制、等过程中为了得到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;
}