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

简介: 项目实战——Qt实现FFmpeg音视频转码器(二)

项目实战——Qt实现FFmpeg音视频转码器(一)https://developer.aliyun.com/article/1474013

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

效果如下:

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));
    }
}

效果如下:

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的音视频转码器

目录
相关文章
|
6月前
|
编解码 编译器
项目实战——Qt实现FFmpeg音视频转码器(一)
项目实战——Qt实现FFmpeg音视频转码器(一)
171 0
|
3月前
|
编解码 NoSQL Java
使用Spring Boot + Redis 队列实现视频文件上传及FFmpeg转码的技术分享
【8月更文挑战第30天】在当前的互联网应用中,视频内容的处理与分发已成为不可或缺的一部分。对于视频平台而言,高效、稳定地处理用户上传的视频文件,并对其进行转码以适应不同设备的播放需求,是提升用户体验的关键。本文将围绕使用Spring Boot结合Redis队列技术来实现视频文件上传及FFmpeg转码的过程,分享一系列技术干货。
200 3
|
3月前
|
编解码 Linux
CentOS安装ffmpeg并转码视频为mp4
CentOS安装ffmpeg并转码视频为mp4
144 0
|
3月前
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
80 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
2月前
|
Android开发 计算机视觉 C++
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
音视频编程对许多程序员来说是一片充满挑战的领域,但借助如OpenCV、LearnOpenGL、FFmpeg、OBS Studio及VLC media player等强大的开源工具,可以降低入门门槛。这些框架不仅覆盖了计算机视觉、图形渲染,还包括多媒体处理与直播技术,通过多种编程语言如Python、C++的应用,使得音视频开发更为便捷。例如,OpenCV支持跨平台的视觉应用开发,FFmpeg则擅长多媒体文件的处理与转换,而VLC media player则是验证音视频文件质量的有效工具。
93 0
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
|
2月前
用ffmpeg提取合并音视频
用ffmpeg提取合并音视频
|
4月前
|
达摩院 语音技术 异构计算
语音识别-免费开源的语音转文本软件Whisper的本地搭建详细教程,python版本是3.805,ffmpeg是专门处理音视频的,ffmpeg的下载链接,现在要求安装python和ffmpeg
语音识别-免费开源的语音转文本软件Whisper的本地搭建详细教程,python版本是3.805,ffmpeg是专门处理音视频的,ffmpeg的下载链接,现在要求安装python和ffmpeg
|
5月前
|
存储 编解码 Linux
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
63 1
|
4月前
|
C#
C#进程调用FFmpeg操作音视频
因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作。本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并、音频合并、音频与视频合并成视频这几个简单的音视频操作。
|
5月前
|
编解码
FFmpeg之转码
FFmpeg之转码