项目实战——Qt实现FFmpeg音视频转码器

这篇具有很好参考价值的文章主要介绍了项目实战——Qt实现FFmpeg音视频转码器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本文记录使用 Qt 实现 FFmepg 音视频转码器项目的开发过程。


一、移植 FFmpeg 相关文件

1、首先创建一个 Qt 项目,选择 MSVC2017 32bit 作为其编译器
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
2、将 FFmpeg 相关库及源文件拷贝到当前目录下
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
3、注释 prepare_app_arguments 函数(这里方便后面我们运行时可以指定相应的转码参数)
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
4、将所需的一些 dll 动态库文件拷贝到 debug 目录下
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
5、将音视频素材文件拷贝到 build-QtVideoConverterFFmpeg431-Desktop_Qt_5_14_2_MinGW_32_bit-Debug目录下(点击运行自动生成的目录)
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

二、绘制 ui 界面

绘制一个简单的 ui 界面,效果如下:
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
里面包括 Frame、Push Button、Progress Bar、Label、Table Widget、Combo Box、Line Edit 等相关控件。

三、实现简单的转码

1、在开始转码按键的 clicked 槽函数加入以下代码:

void Widget::on_pushButton_Running_clicked()
{
    qDebug() << "hello,ffmpeg";

    QString currentPath = QDir::current().path();

       qDebug() << "Current path:" << currentPath;

    char* arrParams[10] = { 0 };
    for (int k = 0; k < 10; k++) {
        arrParams[k] = new char[64]();
    }
    strcpy(arrParams[0], "QtVideoConverter.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);

    AVGeneralMediaInfo* avmi = new AVGeneralMediaInfo();
    for (int k = 0; k < 10; k++) {
        delete[] arrParams[k];
        avmi = NULL;
    }
}

2、点击运行,可以看到如下的界面
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
目前进度条功能还未实现,点击转码可以在 build-QtVideoConverter-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug 目录下看到转码成功的 flv 文件
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

四、功能优化

1、控件布局及美化

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setStyleSheet("background-color:#F0F0F0;");   // 设置组件窗口的外观
    // qss,类似于css
    ui->lblLogoText->setStyleSheet("color:#009100;font-style:italic;font-weight:bold;font-size:30px;");

    // frame 背景色
    ui->frameTop->setStyleSheet("background-color:#C4E1FF;");

    // 按钮背景色
    ui->pushButton_Running->setStyleSheet("background-color:#C4E1FF;font-weight:bold;font-size:30px;color:#009100;border:2px groove gray;border-radius:10px;padding:2px 4px;");
}

// 隐藏栅格线、单元格不可编辑
    ui->tableWidget_FileList->verticalHeader()->setHidden(true); // 设置行名隐藏(注意是行名,不是整行)
    ui->tableWidget_FileList->setShowGrid(false); // 控制视图中数据项之间是否显示网格
    ui->tableWidget_FileList->setEditTriggers(QAbstractItemView::NoEditTriggers); // 让这个表格对用户只读

效果如下:
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

2、缩放界面

事件过滤器:(双击,全屏)

// 事件过滤器:(双击,全屏)
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    // 指定某个控件
    if (obj == ui->frameTop || obj == ui->lblLogoText || obj == ui->lblLogoImage) {
        //  QEvent::MouseButtonPress,QEvent::MouseButtonDblClick
        if (event->type() == QEvent::MouseButtonDblClick) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            if (mouseEvent->button() == Qt::LeftButton) {
                // QMessageBox::information(this, "点击", "点击了我", QMessageBox::Yes | QMessageBox::No | QMessageBox::Yes);
                if (!this->isMaximized()) {
                    this->showMaximized();
                } else {
                    this->showNormal();
                }
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        // pass the event on to the parent class
        return Widget::eventFilter(obj, event);
    }
}

效果:
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频
ESC 键退出全屏

// 按键:(esc--退出全屏)
void Widget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
        case Qt::Key_Escape:
        if (this->isMaximized()) {
            this->showNormal();
        }
        break;
    default:
        QWidget::keyPressEvent(event);
    }
}

3、实现拖拽

鼠标按下不松开,然后移动鼠标实现拖拽,松开鼠标拖拽结束

// 拖拽操作---begin
void Widget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_bDrag = true;
        // 获得鼠标的初始位置
        mouseStartPoint = event->globalPos(); // 事件发生时鼠标相对于我们整个屏幕的左上角(0,0)的偏移值
        // mouseStartPoint = event->pos(); // 事件发生时鼠标相对于当前active widget的左上角(0,0)的偏移值
        // 获得窗口的初始位置
        windowTopLeftPoint = this->frameGeometry().topLeft(); // 仍然表示整个屏幕的左上角

        qDebug() << "mouseStartPoint" << mouseStartPoint.x() << mouseStartPoint.y();
        qDebug() << "windowTopLeftPoint" << windowTopLeftPoint.x() << windowTopLeftPoint.y();
    }
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_bDrag) {
        // 获得鼠标移动的距离
        QPoint distance = event->globalPos() - mouseStartPoint;
        // QPoint distance = event->pos() - mouseStartPoint;
        // 改变窗口的位置
        this->move(windowTopLeftPoint + distance);
        qDebug() << "move" << windowTopLeftPoint + distance;
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_bDrag = false;
    }
}
// 拖拽操作--end

效果如下:
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

4、解析文件

点击 选择文件 按钮,选择待转码的文件,可以将所选文件的相关信息解析出来

void Widget::on_pushButton_AddFile_clicked()
{
    // 定义文件对话框类
    QFileDialog *fileDialog = new QFileDialog(this);
    // 定义文件对话框标题
    fileDialog->setWindowTitle(tr("打开文件")); // tr()函数:Qt会根据当前的语言环境自动选择相应的翻译文件,并将字符串翻译成对应的语言。
    // 设置默认路径
    fileDialog->setDirectory(".");
    // 设置文件过滤器
    fileDialog->setNameFilter(tr("video(*.mp4 *.flv *.mkv);;All files(*.*)"));
    // 设置可以选择多个文件,默认只能选择一个文件 QFileDialog::ExistingFiles
    fileDialog->setFileMode(QFileDialog::ExistingFile);
    // 设置视图模式
    fileDialog->setViewMode(QFileDialog::Detail);

    if (fileDialog->exec()) {
        QString strFileName = fileDialog->selectedFiles()[0];
        qDebug() << strFileName;
        QFileInfo fileinfo;
        fileinfo = QFileInfo(strFileName);

        // 插入数据项
        ui->tableWidget_FileList->setRowCount(1);
        ui->tableWidget_FileList->setItem(0, 0, new QTableWidgetItem(fileinfo.fileName())); // 文件名
        ui->tableWidget_FileList->setItem(0, 1, new QTableWidgetItem(fileinfo.suffix()));   // 后缀

        AVGeneralMediaInfo avmi;
        std::string str = strFileName.toStdString();
        const char *chFilename = str.c_str();
        get_avgeneral_mediainfo(&avmi, chFilename);
        ui->tableWidget_FileList->setItem(0, 2, new QTableWidgetItem(QString(QLatin1String(avmi.videoCodecName))));
        ui->tableWidget_FileList->setItem(0, 3, new QTableWidgetItem(QString(QLatin1String(avmi.audioCodecName))));
        char chDuration[128] = {0};
        sprintf(chDuration, "%lld", avmi.duration);
        ui->tableWidget_FileList->setItem(0, 4, new QTableWidgetItem(QString(QLatin1String(chDuration))));
        ui->tableWidget_FileList->setItem(0, 5, new QTableWidgetItem(strFileName));
    }
}

效果如下:
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

5、开启独立线程

tcworkthread.h

#ifndef TCWORKTHREAD_H
#define TCWORKTHREAD_H

#include <QThread>
extern "C" {
#include "ffmpeg.h"
}

#define MAX_CMDLINE_ARGC_COUNT 100

// 转码参数
typedef struct __TCParams {
    char inFilename[512];
    char videoCodecName[256];
    char audioCodecName[256];
    char muxerName[256];

    // 定义了一个无参数的构造函数__TCParams(),在该构造函数中调用了一个名为__init()的私有成员函数。
    // 构造函数在创建结构体实例时会被自动调用,因此当创建TCParams对象时,会自动执行__init()函数。
    __TCParams() {
        __init();
    }

    void __init() {
        memset(inFilename, 0, 512);
        memset(videoCodecName, 0, 256);
        memset(audioCodecName, 0, 256);
        memset(muxerName, 0, 256);
    }

} TCParams;

class TCWorkThread : public QThread
{
public:
    TCWorkThread();

private:
    virtual void run(); // 任务处理线程
    TCParams *m_pTCParams;

public:
    int workCount;  // 计数
    void SetTCParams(TCParams *params);

signals:

public slots:

};

tcworkthread.c

#include "tcworkthread.h"
#include <QDebug>

TCWorkThread::TCWorkThread()
{
    workCount = 0;
    m_pTCParams = nullptr;
}

void TCWorkThread::SetTCParams(TCParams *params)
{
    m_pTCParams = params;
}

// run() 重新实现
void TCWorkThread::run()
{
    if (m_pTCParams == nullptr) {
        return;
    }

    // by lp,参数都是写死的,仅供参考

    char* arrParams[MAX_CMDLINE_ARGC_COUNT] = { 0 };
    for (int k = 0; k < MAX_CMDLINE_ARGC_COUNT; k++) {
        arrParams[k] = new char[1024]();
    }
    char strOutName[512] = {0};

    strcpy(arrParams[0], "QtVideoConverter.exe");
    strcpy(arrParams[1], "-i");
    strcpy(arrParams[2], m_pTCParams->inFilename);
    strcpy(arrParams[3], "-vcodec");
    strcpy(arrParams[4], m_pTCParams->videoCodecName);
    strcpy(arrParams[5], "-acodec");
    strcpy(arrParams[6], m_pTCParams->audioCodecName);
    strcpy(arrParams[7], "-y");

    sprintf(strOutName, "SampleVideo_1280x720_20mb.%s", m_pTCParams->muxerName);
    strcpy(arrParams[8], strOutName);

    // 准备参数
    main_ffmpeg431(9, arrParams);

    for (int k = 0; k < MAX_CMDLINE_ARGC_COUNT; k++) {
        delete[] arrParams[k];  // 切记要释放申请的内存
        arrParams[k] = NULL;
    }
}

6、开启定时器

// 定时器事件处理函数
// 获取实时转码进度
// 当前进度为 1.00 时,killTimer
void Widget::timerEvent(QTimerEvent *event)
{
    int nPrg = (int)(get_tc_progress() * 100);
    qDebug() << "progress:" << nPrg;
    ui->progressBar_tcprg->setValue(nPrg);
    if (nPrg >= 100) {
        killTimer(m_TimerID1);
    }
}

7、最终运行效果

将本地 mp3 文件转换成 flv 文件
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频

五、附录

附上一个十六进制颜色码的网站:十六进制颜色代码表,图表及调色板

六、资源自取

链接:基于QT和ffmpeg的音视频转码器
项目实战——Qt实现FFmpeg音视频转码器,音视频开发,Qt,qt,ffmpeg,音视频


我的qq:2442391036,欢迎交流!文章来源地址https://www.toymoban.com/news/detail-818013.html


到了这里,关于项目实战——Qt实现FFmpeg音视频转码器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt音视频开发40-ffmpeg采集桌面并录制

    之前用ffmpeg打通了各种视频文件和视频流以及本地摄像头设备的采集,近期有个客户需求要求将整个桌面屏幕采集下来,并可以录制保存成MP4文件,以前也遇到过类似的需求,由于没有搞过,也没有精力去摸索和测试,所以也就一直耽搁着,近期刚好这个需求又来了,定下心

    2023年04月25日
    浏览(66)
  • 音视频开发实战03-FFmpeg命令行工具移植

    作为一个音视频开发者,在日常工作中经常会使用ffmpeg 命令来做很多事比如转码 ffmpeg -y -i test.mov -g 150 -s 1280x720 -codec libx265 -r 25 test_h265.mp4 ,水平翻转视频: ffmpeg -i src.mp4 -vf hflip -acodec copy -vcodec h264 -b 22000000 out.mp4 ,视频截取: ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 ou

    2024年02月16日
    浏览(79)
  • 音视频项目—基于FFmpeg和SDL的音视频播放器解析(三)

    介绍 在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器 如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视

    2024年02月05日
    浏览(72)
  • 音视频项目—基于FFmpeg和SDL的音视频播放器解析(二十一)

    介绍 在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器 如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视

    2024年02月02日
    浏览(75)
  • Qt/C++音视频开发50-不同ffmpeg版本之间的差异处理

    ffmpeg的版本众多,从2010年开始计算的项目的话,基本上还在使用的有ffmpeg2/3/4/5/6,最近几年版本彪的比较厉害,直接4/5/6,大版本之间接口有一些变化,特别是一些废弃接口被彻底删除了,而网络上的各种文章几乎都是ffmpeg3左右为主的,所以本人在写这个全功能播放组件的时

    2024年02月14日
    浏览(56)
  • QtAV:基于Qt和FFmpeg的跨平台高性能音视频播放框架

    目录 一.简介 1.特性 2.支持的平台 3.简单易用的接口 二.编译 1.下载依赖包 2.开始编译 2.1克隆 2.2修改配置文件 2.3编译 三.试用 官网地址:http://www.qtav.org/ Github地址:https://github.com/wang-bin/QtAV ●支持大部分播放功能 ●播放、暂停、播放速度、快进快退、字幕、音量、声道、音

    2024年01月22日
    浏览(161)
  • ffmpeg api实现将音视频混合

    需求: 将一首歌mp3格式,和一段无声音录屏mp4格式,合成到一起,使播放视频时能听到这首歌。 实现原理: 打开mp3音频,解析出输入音频流,再打开mp4视频,解析出输入视频流。 然后打开输出环境,创建2个输出流,分别对应音频输入流和视频输入流。 最后循环交替从音频

    2024年02月14日
    浏览(45)
  • 用Qt开发的ffmpeg流媒体播放器,支持截图、录像,支持音视频播放,支持本地文件播放、网络流播放

    本工程qt用的版本是5.8-32位,ffmpeg用的版本是较新的5.1版本。它支持TCP或UDP方式拉取实时流,实时流我采用的是监控摄像头的RTSP流。音频播放采用的是QAudioOutput,视频经ffmpeg解码并由YUV转RGB后是在QOpenGLWidget下进行渲染显示。本工程的代码有注释,可以通过本博客查看代码或者

    2024年02月03日
    浏览(105)
  • FFmpeg 播放器实现音视频同步的三种方式

    我们基于 FFmpeg 利用 OpenGL ES 和 OpenSL ES 分别实现了对解码后视频和音频的渲染,本文将实现播放器的最后一个重要功能:音视频同步。 老人们经常说, 播放器对音频和视频的播放没有绝对的静态的同步,只有相对的动态的同步,实际上音视频同步就是一个“你追我赶”的过

    2024年02月06日
    浏览(66)
  • 音视频开发:ffplay使用ffmpeg滤镜实现倍速播放

    曾经为实现倍速播放使用过ffmpeg,对音频使用atempo滤镜即可实现变速不变调。但是当时效果并不是特别好,和soundtouch相比处理后的音质有明显的区别。最近用新版本的ffmpeg滤镜重新实现了倍速播放,发现效果变好,已经达到可接受的程度,所以在此分享具体实现。 ffmpeg倍速

    2024年02月03日
    浏览(110)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包