QProcess 调用 ffmpeg来处理音频

这篇具有很好参考价值的文章主要介绍了QProcess 调用 ffmpeg来处理音频。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目场景:

在文章 qt 实现音视频的分贝检测系统中,实现的是边播放变解析音频数据来统计音频的分贝大小,并不满足实际项目的需求,有的视频声音正常,有的视频声音就偏低,即使放到最大音量声音也是比较小,本文的目的是直接通过对本地视频进行检测,拿出关键指标,来进行对音频处理

关键依赖:ffmpeg

因为依赖于ffmpeg的能力,所以第一步要安装ffmpeg环境,自行百度

步骤1,检测max_volume 值是否小于0dB

 ffmpeg -i 1.mp3  -filter_complex volumedetect -c:v copy -f null /dev/null

QProcess 调用 ffmpeg来处理音频,《Qt 项目实战经历全记录》,音视频开发,ffmpeg,音视频,QProcess,Qt
其中检测的关键指标就是 max_volume, 本次检测和处理的目标就是把 max_volume的值给提高到0dB;

步骤2,如何区分是音频文件还是视频文件

可以有多种方法,1可以通过后缀名来区分; 2 因为代码是用qt写的,可以用qt来实现,代码如下

QFileInfo f(1.mp3”);
if(f.completeSuffix() == "mp3" || f.completeSuffix() == "aac" || 
f.completeSuffix() == "amr" || f.completeSuffix() == "wav" || f.completeSuffix() == "wma" )
QMediaPlayer p;
p.audioAvailable()

步骤3,处理音频,使max_volume的值接近0dB

音频文件用以下指令

ffmpeg -i 1.mp3-af  "volume=5.8dB"  out.mp3

如果是视频文件,用以下指令:(保持视频信息不变,当然还设计到音频的编码格式)

ffmpeg -i 1.mp3-af  "volume=5.8dB" -c:v copy -c:a aac out.mp3

输出如下
QProcess 调用 ffmpeg来处理音频,《Qt 项目实战经历全记录》,音视频开发,ffmpeg,音视频,QProcess,Qt
QProcess 调用 ffmpeg来处理音频,《Qt 项目实战经历全记录》,音视频开发,ffmpeg,音视频,QProcess,Qt

程序设计思路

通过QProcess 调用 ffmpeg指令,检测max_volume小于0的文件,拿到文件列表,再通过ffmpeg指令来提高音频。关键代码如下:

dbdetectthread.h

#ifndef DBDETECTTHREAD_H
#define DBDETECTTHREAD_H

#include <QObject>
#include <QThread>
#include <QProcess>
#include <QStringList>

class DbDetectThread : public QThread
{
    Q_OBJECT
public:
    explicit DbDetectThread(QObject *parent = nullptr);
    void setList(const QStringList &list);
    virtual void run();
signals:
    void sigPath(const QString &p, float db);
    void sigMsg(const QString &p);
    void sigEnd();

public slots:
    void readStandardOutput();
    void readStandardError();
    void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
    void threadFinished(); //线程退出

private:
    QProcess *pCmdProcess;
    QStringList pathlist;
    QString curFile;
};

#endif // DBDETECTTHREAD_H

dbdetectthread.cpp

#include "dbdetectthread.h"
#include <QDebug>
DbDetectThread::DbDetectThread(QObject *parent)
    : QThread{parent}
{
    qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
}

void DbDetectThread::setList(const QStringList &list)
{
    pathlist = list;
}

//ffmpeg -i 2.wav -filter_complex volumedetect -c:v copy -f null /dev/null

//需要计算分贝相差值
//ffmpeg  -i 2.wav -filter:a "volume=80dB" output2.wav

void DbDetectThread::run()
{
    pCmdProcess = new QProcess();    //不要加this
    connect(pCmdProcess, &QProcess::readyReadStandardOutput, this, &DbDetectThread::readStandardOutput);
    connect(pCmdProcess, &QProcess::readyReadStandardError, this, &DbDetectThread::readStandardError);
    connect(pCmdProcess, QOverload<int , QProcess::ExitStatus >::of(&QProcess::finished), this, &DbDetectThread::processFinished);
    connect(this, &QThread::finished, this, &DbDetectThread::threadFinished);

    QStringList arguments;
    //arguments << "-i" << "C:/Users/wmm/Desktop/DbDetect/voice/input.mp4" << "-c:v" << "h264" << "-c:a" << "aac" << "C:/Users/wmm/Desktop/DbDetect/voice/output.mp4";
    //arguments << "-i" << "input.mp4" << "-c:v" << "h264" << "-c:a" << "aac" << "output.mp4";
    //arguments << "-i" << p << "-filter_complex"<< "volumedetect" <<  "-c:v" << "copy" << "-f" << "null" << "/dev/null";
    //QString cmd = QString("ffmpeg -i %1 -filter_complex volumedetect -c:v copy -f null /dev/null").arg(p);

    //QString cmd = QString("ffmpeg -i C:/Users/wmm/Desktop/DbDetect/voice/input.mp4 -filter_complex volumedetect -c:v copy -f null /dev/null");
    //QString cmd = "ping www.baidu.com -w 500";
    //QString result;
    foreach(auto p, pathlist)
    {
        curFile = p;
        qDebug() << "start detect " << curFile;
        QString cmd = QString("ffmpeg -i %1 -filter_complex volumedetect -c:v copy -f null /dev/null").arg(p);
        pCmdProcess->start(cmd/*,arguments*/);
        pCmdProcess->waitForFinished();
        sleep(1);
    }

}

void DbDetectThread::readStandardOutput() {
    qDebug() << "Standard output: " << pCmdProcess->readAllStandardOutput();
}

void DbDetectThread::readStandardError() {
    QString errorMessage = QString::fromUtf8(pCmdProcess->readAllStandardError());
    QStringList errlist = errorMessage.split("\r\n");
    //qDebug() << errlist.size();
    //qDebug() << errlist;

//    float num = 3.1415926;
//    QString str = QString::number(num, 'f', 2);

    foreach (auto p, errlist) {
        if(p.contains("max_volume"))
        {
            qDebug() << p;
            int pos = p.indexOf("max_volume");
            int pos2 = p.indexOf("dB",pos);
            QString val = p.mid(pos+11,pos2-11-pos);

            qDebug() <<val;
            float fval = val.toFloat();
            qDebug() << fval;

            if(fval <0)
            {
                qDebug() << "小于0";
                emit sigPath(curFile,fval);
            }
            else
            {
                qDebug() << "不小于0";
            }
        }
    }
        // 对 errorMessage 进行解析和处理...
    //qDebug() << "Standard error: " << pCmdProcess->readAllStandardError();
}

void DbDetectThread::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
    qDebug() << "Process finished with exit code" << exitCode << "and exit status" << exitStatus << ((QProcess*)QObject::sender())->arguments();
    emit sigMsg(QString("%1 检测完成,exitCode = %2, exitStatus = %3 ").arg(curFile).arg(exitCode).arg(exitStatus));
}

void DbDetectThread::threadFinished()
{
    qDebug() << __func__;
    emit sigEnd();
    pCmdProcess->deleteLater();
}

dbprocessthread.h

#ifndef DBPROCESSTHREAD_H
#define DBPROCESSTHREAD_H

#include <QObject>
#include <QThread>
#include <QProcess>
#include <QMap>
#include <QMediaPlayer>
class DbProcessThread : public QThread
{
    Q_OBJECT
public:
    explicit DbProcessThread(QObject *parent = nullptr);

    void setOutputDir(const QString &dir);
    void setMap(const QMap<QString,float> &map);
    virtual void run();
signals:
    void sigPath(const QString &p, float db);
    void sigMsg(const QString &p);
    void sigEnd();

public slots:
    void readStandardOutput();
    void readStandardError();
    void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
    void threadFinished(); //线程退出

private:
    QProcess *pCmdProcess;
    QMediaPlayer  mediaPlayer;
    QMap<QString,float> m_needProcessMap;
    QString m_outputDir;
    QString m_curSrcFile;
    QString m_curDesFile;
};

#endif // DBPROCESSTHREAD_H

dbprocessthread.cpp

#include "dbprocessthread.h"
#include <QDebug>
#include <QFileInfo>
DbProcessThread::DbProcessThread(QObject *parent)
    : QThread{parent}
{

}

void DbProcessThread::setOutputDir(const QString &dir)
{
    m_outputDir = dir;
}

void DbProcessThread::setMap(const QMap<QString, float> &map)
{
    m_needProcessMap = map;
}

void DbProcessThread::run()
{
    pCmdProcess = new QProcess();    //不要加this
    connect(pCmdProcess, &QProcess::readyReadStandardOutput, this, &DbProcessThread::readStandardOutput);
    connect(pCmdProcess, &QProcess::readyReadStandardError, this, &DbProcessThread::readStandardError);
    connect(pCmdProcess, QOverload<int , QProcess::ExitStatus >::of(&QProcess::finished), this, &DbProcessThread::processFinished);
    connect(this, &QThread::finished, this, &DbProcessThread::threadFinished);

    QMapIterator<QString, float> i(m_needProcessMap);
    while (i.hasNext()) {
        i.next();
        QFileInfo f(i.key());
        qDebug() << f.fileName() << m_outputDir+"/" + f.fileName();
        m_curSrcFile = i.key();
        m_curDesFile = m_outputDir+"/" + f.fileName();
        QStringList arguments;
        //arguments << "-i" << i.key() << "-c:v" << "h264" << "-c:a" << "aac" << m_outputDir+"/" + f.fileName();
        arguments << "-i" << i.key() << "-af" << QString("volume=%1dB").arg(qAbs(i.value())) << "-c:v copy" << " -c:a aac "  << m_outputDir+"/" + f.fileName();
        qDebug() << arguments;
        emit sigMsg(QString("正在处理...%1").arg(m_curSrcFile));

        if(f.completeSuffix() == "mp3" || f.completeSuffix() == "aac" || f.completeSuffix() == "amr" || f.completeSuffix() == "wav"\
                 || f.completeSuffix() == "wma" )
        {
            pCmdProcess->start(QString("ffmpeg -i %1 -af \"volume=%2dB\"  %3").arg(i.key()).arg(qAbs(i.value())).arg(m_outputDir+"/" + f.fileName())/*,arguments*/);
        }
        else {
            pCmdProcess->start(QString("ffmpeg -i %1 -af \"volume=%2dB\" -c:v copy  %3").arg(i.key()).arg(qAbs(i.value())).arg(m_outputDir+"/" + f.fileName())/*,arguments*/);
        }

        //pCmdProcess->start(QString("ffmpeg -i %1 -af \"volume=%2dB\" -c:v copy -c:a aac %3").arg(i.key()).arg(qAbs(i.value())).arg(m_outputDir+"/" + f.fileName())/*,arguments*/);
        pCmdProcess->waitForFinished();
        msleep(500);
    }

}

void DbProcessThread::readStandardOutput() {
    qDebug() << "Standard output: " << pCmdProcess->readAllStandardOutput();
}

void DbProcessThread::readStandardError() {
    qDebug() << "Standard error: " << pCmdProcess->readAllStandardError();
}

void DbProcessThread::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
    qDebug() << "Process finished with exit code" << exitCode << "and exit status" << exitStatus << ((QProcess*)QObject::sender())->arguments();
    emit sigMsg(QString("%1 处理完成,文件保存为%2,exitCode = %3, exitStatus = %4 ").arg(m_curSrcFile).arg(m_curDesFile).arg(exitCode).arg(exitStatus));
}

void DbProcessThread::threadFinished()
{
    qDebug() << __func__;
    emit sigEnd();
    pCmdProcess->deleteLater();
}

效果如图:
QProcess 调用 ffmpeg来处理音频,《Qt 项目实战经历全记录》,音视频开发,ffmpeg,音视频,QProcess,Qt
代码上传到此 https://download.csdn.net/download/u011942101/88299291文章来源地址https://www.toymoban.com/news/detail-700151.html

到了这里,关于QProcess 调用 ffmpeg来处理音频的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • QT笔记——QProcess学习

    我们常常想通过某一个类,来启动一个外部进程 本文将讲解如何通过QProcess来进行启动外部进程 一:了解QProcess QProcess是Qt框架提供的一个类,用于在应用程序中执行外部进程。它提供了一系列函数来启动、控制和与外部进程进行交互 1.启动进程的方式: (1.1)分离式:外部程序

    2024年02月12日
    浏览(37)
  • 深入浅出:FFmpeg 音频解码与处理AVFrame全解析

    FFmpeg 是一个开源的音视频处理软件,它包含了一系列的库和程序,用于处理音频、视频和其他多媒体数据。FFmpeg 的名字来源于 “Fast Forward MPEG”,其中 MPEG 是一种常见的音视频编码标准。 FFmpeg 项目于 2000 年由 Fabrice Bellard 启动,他是 QEMU(一种开源的计算机模拟器和虚拟机

    2024年02月04日
    浏览(115)
  • QT6调用音频输入输出(超详细)

      目录  一、QT6音频调用与QT5的区别 1.QAudioSource代替QAudioInput类 2.QAudioSink代替QAudioOutput类 二、音频操作中Push和Pull的区别 三、依托于Websocket实现实时对讲机 1.AudioIputDevices类 2.AudioOutputDevices类 3.实现的AudioHandler类完整内容  本人实际是要完成一个类似于对讲机的通话小Demo,并

    2024年02月20日
    浏览(36)
  • C++ Qt开发:QProcess进程管理模块

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用 QProcess 组件实现针对进程的控制管理等。 当你在使用Qt进行跨平台应

    2024年03月22日
    浏览(34)
  • QT之执行外部程序 QProcess,实时获取该程序的标准输出

    在开发项目中很容易就需要执行外部程序,今天我说一下我执行的外部程序,是怎么样调用,怎样调坑的。 QT给我们提供了QProcess: 且提供了非常多的函数供我们使用,使用次数最多的就是: 创建_process对象时也要注意: 但是很多时候是执行没有结果的,返回一个正常结束

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

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

    2024年02月14日
    浏览(56)
  • RK3588实战:调用npu加速,yolov5识别图像、ffmpeg发送到rtmp服务器

    前言:最近在学习一些rk3588相关的东西,趁着这个项目,把学习的相关东西整合下,放到一个项目里面,巩固学习的知识。 项目名称:yolov5识别图像、ffmpeg发送到rtmp服务器 功能:1、opencv读取usb摄像头,使用RK3588自带的NPU推理yolov5s算法,识别图像            2、使用ffmpeg,

    2024年02月03日
    浏览(44)
  • qt-C++笔记之QProcess声明在堆上和声明在栈上对进程执行是否异步的影响

    —— 2024-04-13 选择在堆上或栈上声明 QProcess 主要影响的是对象的生命周期管理,而不直接影响进程的异步执行方式。不论选择哪种方式, QProcess 的异步性质都由其设计决定,与声明方式无关。因此,应基于项目需求和资源管理考量来选择合适的声明方式。 在 Qt 编程中, Q

    2024年04月14日
    浏览(42)
  • Qt 项目A调用项目B方法(项目架构管理)

    项目开发中,如果项目比较大,大多采用多项目的方式,主要是为了方便代码管理,也更开发变得更加方便。操作如下: 注:我用的版本是Qt 5.12.3 要求: 1、项目A为主,项目B为辅; 2、定位:A为主要实现业务上界面交互,B为A提供方法支持,相当于将B作为一个可实时编辑的

    2023年04月18日
    浏览(40)
  • 【Android入门到项目实战-- 7.4】—— 如何播放音频和视频

    目录 一、播放音频  MediaPlayer的工作流程 具体代码实现 二、播放视频 具体代码实现         学完本篇文章可以收获如何播放音频和视频。         播放音频需要使用MediaPlayer类实现,它对各种格式的音频文件提供了全面的控制方法,下面是MediaPlayer类较为常用的控制方

    2024年02月01日
    浏览(51)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包