Qt ffmpeg音视频转换工具

Qt ffmpeg音视频转换工具,QProcess方式调用ffmpeg,对音视频文件进行格式转换,支持常见的音视频格式,主要在于QProcess的输出处理以及转换的文件名和后缀的处理,可以进一步加上音视频剪切合并和音视频文件属性查询修改的功能。

Qt ffmpeg音视频转换工具_第1张图片

Qt ffmpeg音视频转换工具_第2张图片

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QFont font;
    font.setPixelSize(16);
    setFont(font);

    setWindowTitle(QStringLiteral("ffmpeg工具"));

    ui->listWidget->setMaximumWidth(200);
    connect(ui->listWidget, SIGNAL(clicked(QModelIndex)), this, SLOT(convert()));

    ui->checkBox->setChecked(true);

    mProcess = new QProcess;
    connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(readError()));
    connect(mProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
    connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)));

    mTimer = new QTimer(this);
    connect(mTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    mTimer->start(1000);

    initListWidget();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::readError()
{
    QString str = mProcess->readAllStandardError().data();

    if (str == "\r")
    {
        ui->textBrowser->append(mTmpStr);
        mTmpStr.clear();
    }
    else
    {
        mTmpStr += str;
        if (str.contains("\r\n"))
        {
            ui->textBrowser->append(mTmpStr);
            mTmpStr.clear();
        }
    }
}

void MainWindow::readOutput()
{
    QByteArray qba = mProcess->readAllStandardOutput();
    QTextCodec* tc = QTextCodec::codecForName("System");
    QString str = tc->toUnicode(qba);

    if (str == "\r")
    {
        ui->textBrowser->append(mTmpStr);
        mTmpStr.clear();
    }
    else
    {
        mTmpStr += str;
        if (str.contains("\r\n"))
        {
            ui->textBrowser->append(mTmpStr);
            mTmpStr.clear();
        }
    }
}

void MainWindow::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
    ui->textBrowser->append(QStringLiteral("finished : %1 %2").arg(exitCode).arg(exitStatus));
    mProcess->close();

    if (exitCode == 0 && exitStatus == 0)
    {
        informationMessageBox(QStringLiteral("提示"), QStringLiteral("%1\n转换\n%2\n完成").arg(mSourceFile).arg(mTargetFile));
    }
    else
    {
        informationMessageBox(QStringLiteral("提示"), QStringLiteral("%1\n转换\n%2\n失败").arg(mSourceFile).arg(mTargetFile));
    }
}

void MainWindow::updateTimer()
{
    if (!mTmpStr.isEmpty())
    {
        ui->textBrowser->append(mTmpStr);
        mTmpStr.clear();
    }
}

void MainWindow::initListWidget()
{
    QStringList nameLst;
    nameLst.append(QStringLiteral("FLAC转MP3")); // ffmpeg -i input.flac -ab 320k -map_metadata 0 -id3v2_version 3 output.mp3
    nameLst.append(QStringLiteral("M4A转MP3")); // ffmpeg -i 1.m4a -acodec libmp3lame -aq 0 123.mp3
    nameLst.append(QStringLiteral("WAV转MP3")); // ffmpeg -i input.wav -f mp3 -acodec libmp3lame -aq 0 output.mp3
    nameLst.append(QStringLiteral("APE转MP3")); // ffmpeg -i 1.ape -acodec libmp3lame -aq 0 123.mp3
    nameLst.append("");
    nameLst.append(QStringLiteral("MP4转M4A")); // ffmpeg -i test.mp4 -acodec copy -vn 123.m4a
    nameLst.append(QStringLiteral("MP4转AAC")); // ffmpeg -i test.mp4 -acodec copy -vn 123.aac
    nameLst.append(QStringLiteral("MP4转MP3")); // ffmpeg -i test.mp4 -acodec libmp3lame -aq 0 123.mp3
    nameLst.append("");
    nameLst.append(QStringLiteral("MP3转OGG")); // ffmpeg -i bb.mp3 -acodec libvorbis -ab 128k bb.ogg
    nameLst.append(QStringLiteral("MP3转WAV")); // ffmpeg -i input.mp3 -f wav output.wav

    QMap cmdMap;
    cmdMap.insert(QStringLiteral("FLAC转MP3"), QStringLiteral("ffmpeg -i \"%1\" -ab 320k -map_metadata 0 -id3v2_version 3 -aq 0 \"%2\""));
    cmdMap.insert(QStringLiteral("M4A转MP3"), QStringLiteral("ffmpeg -i \"%1\" -acodec libmp3lame -aq 0 \"%2\""));
    cmdMap.insert(QStringLiteral("WAV转MP3"), QStringLiteral("ffmpeg -i \"%1\" -f mp3 -acodec libmp3lame -aq 0 \"%2\""));
    cmdMap.insert(QStringLiteral("APE转MP3"), QStringLiteral("ffmpeg -i \"%1\" -acodec libmp3lame -aq 0 \"%2\""));
    cmdMap.insert(QStringLiteral("MP4转M4A"), QStringLiteral("ffmpeg -i \"%1\" -acodec copy -vn \"%2\""));
    cmdMap.insert(QStringLiteral("MP4转AAC"), QStringLiteral("ffmpeg -i \"%1\" -acodec copy -vn \"%2\""));
    cmdMap.insert(QStringLiteral("MP4转MP3"), QStringLiteral("ffmpeg -i \"%1\" -acodec libmp3lame -aq 0 \"%2\""));
    cmdMap.insert(QStringLiteral("MP3转OGG"), QStringLiteral("ffmpeg -i \"%1\" -acodec libvorbis -ab 128k \"%2\""));
    cmdMap.insert(QStringLiteral("MP3转WAV"), QStringLiteral("ffmpeg -i \"%1\" -f wav \"%2\""));

    foreach (QString name, nameLst)
    {
        QListWidgetItem *item = new QListWidgetItem;
        if (!name.isEmpty())
        {
            item->setText(name);
            item->setData(Qt::UserRole, cmdMap.value(name));
        }
        else
        {
            item->setText("");
            item->setData(Qt::UserRole, "");
        }
        ui->listWidget->addItem(item);
    }
}

QString MainWindow::getFileSuffix(QString file)
{
    QString ret;

    if (file == "FLAC")
    {
        ret = QStringLiteral("flac");
    }
    else if (file == "MP3")
    {
        ret = QStringLiteral("mp3");
    }
    else if (file == "M4A")
    {
        ret = QStringLiteral("m4a");
    }
    else if (file == "WAV")
    {
        ret = QStringLiteral("wav");
    }
    else if (file == "APE")
    {
        ret = QStringLiteral("ape");
    }
    else if (file == "AAC")
    {
        ret = QStringLiteral("aac");
    }
    else if (file == "MP4")
    {
        ret = QStringLiteral("mp4");
    }
    else if (file == "OGG")
    {
        ret = QStringLiteral("ogg");
    }

    return ret;
}

void MainWindow::convert()
{
    QListWidgetItem *item = ui->listWidget->currentItem();
    QString tmp = item->data(Qt::UserRole).toString();

    if (mProcess->isOpen())
    {
        mProcess->close();
    }

    mSourceFile.clear();
    mTargetFile.clear();
    mSource.clear();
    mTarget.clear();
    mSourceSuffix.clear();
    mTargetSuffix.clear();

    if (!tmp.isEmpty())
    {
        mTitle = item->text();
        mCmd = tmp;
        setWindowTitle(QStringLiteral("ffmpeg工具 - %1").arg(mTitle));
    }
    else
    {
        mTitle.clear();
        mCmd.clear();
        setWindowTitle(QStringLiteral("ffmpeg工具"));
    }
}

bool MainWindow::informationMessageBox(const QString &title, const QString &text, bool isOnlyOk)
{
    QMessageBox msgBox(this);
    msgBox.setFont(this->font());
    msgBox.setIcon(QMessageBox::Information);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    if (isOnlyOk)
    {
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setButtonText(QMessageBox::Ok, QStringLiteral("确定"));
    }
    else
    {
        msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
        msgBox.setButtonText(QMessageBox::Ok, QStringLiteral("确定"));
        msgBox.setButtonText(QMessageBox::Cancel, QStringLiteral("取消"));
    }

    return (msgBox.exec() == QMessageBox::Ok);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (informationMessageBox(QStringLiteral("提示"), QStringLiteral("确定关闭"), false))
    {
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void MainWindow::on_pushButton_import_clicked()
{
    if (mTitle.isEmpty() || mCmd.isEmpty())
    {
        return;
    }

    mSource = mTitle.split(QStringLiteral("转"))[0];
    mTarget = mTitle.split(QStringLiteral("转"))[1];
    mSourceSuffix = getFileSuffix(mSource);
    mTargetSuffix = getFileSuffix(mTarget);

    if (mSourceSuffix.isEmpty() || mTargetSuffix.isEmpty())
    {
        informationMessageBox(QStringLiteral("提示"), QStringLiteral("不支持的文件格式"));
        return;
    }

    QString file = QFileDialog::getOpenFileName(this, QStringLiteral("打开%1文件").arg(mSource), QStringLiteral("."), QStringLiteral("%1文件(*.%2)").arg(mSource).arg(mSourceSuffix));
    if (!file.isEmpty())
    {
        mSourceFile = file;
        if (ui->checkBox->isChecked())
        {
            QString tmp = mSourceFile;
            mTargetFile = tmp.replace(QStringLiteral(".%1").arg(mSourceSuffix), QStringLiteral(".%1").arg(mTargetSuffix));
        }
    }
}

void MainWindow::on_pushButton_save_clicked()
{
    if (mSourceFile.isEmpty())
    {
        return;
    }

    QString file = QFileDialog::getSaveFileName(this, QStringLiteral("保存%1文件").arg(mTarget), mTargetFile, QStringLiteral("%1文件(*.%2)").arg(mTarget).arg(mTargetSuffix));
    if (!file.isEmpty())
    {
        mTargetFile = file;
    }
}

void MainWindow::on_pushButton_convert_clicked()
{
    if (mSourceFile.isEmpty() || mTargetFile.isEmpty())
    {
        return;
    }

    QString cmd = mCmd.arg(mSourceFile).arg(mTargetFile);
    ui->textBrowser->append("\n" + cmd + "\n");

    if (mProcess->isOpen())
    {
        mProcess->close();
    }

    mTmpStr.clear();
    mProcess->start(cmd);
}

你可能感兴趣的:(qt,ffmpeg,开发语言)