背景
QT提供界面调用ffmpeg可执行程序为指定视频,添加执行字幕文件。
QT界面提供视频文件选择,字幕文件选择。
调用ffmpeg可执行程序,执行转码,以及字幕文件添加。
相关功能代码
QT获取应用程序路径
QString FileDirectory::getApplicationDirPath()
{
// QString QApplication::applicationDirPath()
QString applicationDirPath = QApplication::applicationDirPath();
qDebug()<< "applicationDirPath:" << applicationDirPath;
return applicationDirPath;
}
QDir::toNativeSeparators将文件路劲转换成当前系统的标准路径
QProcess::startDetached("explorer " + (QDir::toNativeSeparators(filename)) );
指定当前工作路径
p.setWorkingDirectory("E:/test_rar_course/");//指定进程的工作目录
QProces 启动一个进程
基本方法
用QProcess调用外部程序时,可直接指定命令行参数
QProcess process;
process.start("./process", QStringList()<<"a"<<"b");
process.start("./process a b");
后一种写法看起来写起来比较简洁,但是程序路径或参数中包括空格时,就不如第一种方便了。
QString command = "E:/rar.exe";
QStringList args;
args.append("a");
args.append("-k");
args.append("-r");
args.append("-s");
QProcess p(0);
p.start(command,args); //command是要执行的命令,args是参数
p.waitForFinished();//等待完成
qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());
在QProcess下,我们使用
QProcess::readAllStandardOutput ()
获取标准输出
QProcess::setStandardOutputFile()
设置输出到的文件,相当于前面的重定向
用QProcess读取标准出错,和前面标准输出是类似的:
QProcess::readAllStandardError()
QProcess::setStandardErrorFile()
QProcess process;
process.start("./process", QStringList()<<"a"<<"b");
process.readAllStandardOutput();
获取程序返回值
在Windows下,通过
C:\> process.exe
C:\> echo %errorlevel%
在Linux下,通过
$ ./process
$ echo $?
在QProcess下,则通过:
int QProcess::execute()
int QProcess::exitCode()
捕获键盘消息
QKeyEvent tabKey(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QCoreApplication::sendEvent(this, &tabKey);
相关问题
windows下路径问题
使用绝对路径需要注意特殊字符,如反斜杠,空格等
ffmpeg -i c:\users\home\desktop\input.mp4 -filter_complex "subtitles=c\\:\\\\users\\\\home\\\\desktop\\\\subs.srt:force_style='OutlineColour=&H80000000,BorderStyle=4,Outline=1,Shadow=0,MarginV=20,Fontsize=10,PrimaryColour=&H0000ff&'" c:\users\home\desktop\output.mp4
如果在subtitle中使用全路径,需要添加反斜杠,如下所示:
ffmpeg -i “C:\Users\sadegh\Desktop\subtitle\2\pod 1.mp4” -filter:v subtitles='C:/Users/sadegh/Desktop/subtitle/2/done.ass' “C:\Users\sadegh\Desktop\subtitle\2\pod_result.mkv”
subtitles后面通过反斜杠表明是一个单引号,结尾亦然。 下面这种方法会报错:
got this error error: Unable to parse option value “Usersuser1Desktopsubtitle2done.ass” as image size then i tried this: command: ffmpeg -i
"subtitles=C:\somefilepath.txt"
可以直接写全命令,但是路径中不能有特殊字符如空格等。
poc = new QProcess(this);
QString command = QString("ffmpeg -i F:rawvideo/1.mp4 -pass 1 -y F:/rawvideo/1xxx1.mp4");
connect(poc, SIGNAL(readyReadStandardOutput()), this, SLOT(sltOnReadOutput()));
connect(poc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onFinished(int, Process::ExitStatus)));
poc->setProcessChannelMode(QProcess::MergedChannels);
poc->start(command);
示例2:
QProcess process;
process.start("ffmpeg -t 30 -i C:\\test.mp3 -acodec copy C:\\test2.mp3");
process.waitForFinished();
process.close();
QProcess进程终止
QProcess::terminate()
调用该函数相当于Linux中对一个进程发送terminate信号SIGTERM;该信号是可以被捕捉的,程序可以自行决定终止之前执行的操作,甚至可以忽略这个信号。在windows中虽然没有信号,但是这个函数的作用是相同的,有可能不能终止程序,也允许能够被终止的程序在终止之前做一些终止前的工作。
QPorcess::kill()
Kills the current process, causing it to exit immediately.
On Windows, kill() uses TerminateProcess, and on Unix and macOS, the SIGKILL signal is sent to the process.
立即终止目标程序,令其无条件立即终止,且在函数执行后程序没有机会执行后续代码。相当于Linux及Mac中的SIGKILL信号,相当于Windows的TerminateProcess。
If you’re starting a non-detached process, then QProcess gives you all the tools you need. You can use either QProcess::kill or QProcess::terminate, as needed. No winapi needed.
int main(int argc, char ** argv) {
QApplication app(argc, argv);
QPushButton kill("Kill");
kill.show();
QProcess process;
process.start("rsync ...");
QObject::connect(&kill, &QPushButton::clicked, &process, &QProcess::kill);
QObject::connect(&process, &QProcess::finished, &app, &QCoreApplication::quit);
return app.exec();
}
If you were to start a detached process, then the startDetached method can output a pid that you can use with native api.
参考资料
https://blog.csdn.net/dbzhang800/article/details/6876451
Qt+FFMPEG编写适合自己的批量视频转换程序
https://superuser.com/questions/1242652/is-it-possible-to-give-input-and-output-filess-absolute-path