QT中使用 QProcess接口 执行 fmmpeg命令,实现简单的音视频处理

2023-11-18

QProcess 介绍

"QProcess" 是 Qt 框架中用于启动外部进程和与之进行交互的类。它提供了一个方便的接口,允许你执行外部命令并捕获其输出、错误信息以及监控其运行状态。通过使用 "QProcess" 类,你可以在你的 Qt 应用程序中调用其他的可执行文件,比如系统命令行工具或者其他应用程序,然后处理它们的输出结果或者与其进行交互。

使用流程

#include <QProcess>


QProcess *ffmpegProcess= new QProcess(this);

// 设置要执行的外部命令和参数
QString program = "ffmpeg"; // FFmpeg 命令(假设已将 FFmpeg 添加到系统环境变量)
//转码参数
QStringList arguments;
arguments << "-i" << "input.mp4" << "-c:v" << "h264" << "-c:a" << "aac" << "output.mp4"; // 设

    // 启动外部进程
ffmpegProcess.start(program, arguments);


//如果需要获取外部进程的输出,可以连接“QProcess” 的信号和槽函数
connect(ffmpegProcess, &QProcess::readyReadStandardOutput, this, &YourClass::onReadyReadStandardOutput);
connect(ffmpegProcess, &QProcess::readyReadStandardError, this, &YourClass::onReadyReadStandardError);

//在相应的槽函数中处理外部进程的输出:
void YourClass::onReadyReadStandardOutput()
{
    QByteArray output = ffmpegProcess->readAllStandardOutput();
    // 处理标准输出数据
}

void YourClass::onReadyReadStandardError()
{
    QByteArray error = ffmpegProcess->readAllStandardError();
    // 处理标准错误输出数据
}


ffmpegProcess->waitForFinished(); // 阻塞当前线程,直到进程完成



注意事项

请注意,此示例中的代码是同步执行的,即在调用 waitForFinished 后,程序会等待 FFmpeg 进程完成转码操作。如果你希望异步执行转码,并在转码过程中继续运行其他任务,可以使用 QProcess::startDetached 方法。
即使用startDetached () 替换 start()方法。

关于startDetached ()介绍:

bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr);

参数说明:

program: 一个QString类型的参数,表示要启动的外部应用程序的路径或可执行文件的名称。
arguments: 一个QStringList类型的参数,表示启动外部应用程序时传递给它的命令行参数列表。
workingDirectory: 一个可选的QString类型的参数,表示启动外部应用程序时使用的工作目录。如果不提供此参数,默认使用当前程序的工作目录。
pid: 一个可选的qint64类型的指针参数,用于获取启动的新进程的进程ID。如果不需要获取进程ID,可以将该参数设置为nullptr。
函数返回值:

如果成功启动了新进程,则返回true。
如果启动进程失败或遇到错误,则返回false。

使用QProcess::startDetached函数时,注意以下几点:

该函数启动的进程是独立于当前程序的,所以在当前程序退出后,新进程会继续在后台运行。
由于该函数是无阻塞的,因此在调用该函数后,程序会立即继续执行后续代码,不会等待新进程的执行完成。
如果要与启动的进程进行交互或获取其输出结果,可以考虑使用QProcess的其他相关方法,如QProcess::start和QProcess::waitForFinished。
需要注意的是,QProcess::startDetached函数在不同的操作系统上可能有一些行为上的差异,因此在使用时最好查阅官方文档,以及考虑处理潜在的错误和异常情况。

进一步的,使用ffmpeg 转码音视频流,并且获取音视频流:

可以使用 QProcess 的 setReadChannel() 方法来设置要读取的通道,然后使用 QProcess 的 readAllStandardOutput() 方法来获取输出。

例子:

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 创建一个 QProcess 对象
    QProcess ffmpegProcess;

    // 设置要执行的外部命令和参数
    QString program = "ffmpeg"; // FFmpeg 命令(假设已将 FFmpeg 添加到系统环境变量)
    QStringList arguments;
    arguments << "-i" << "input.mp4" << "-c:v" << "h264" << "-c:a" << "aac" << "-f" << "matroska" << "-"; // 设置转码参数并将输出格式设置为 matroska

    // 设置标准输出读取通道
    ffmpegProcess.setReadChannel(QProcess::StandardOutput);

    // 启动外部进程
    ffmpegProcess.start(program, arguments);

    // 等待进程完成
    if (ffmpegProcess.waitForFinished(-1)) {
        // 进程已完成
        qDebug() << "转码完成!";

        // 读取转码后的视频流
        QByteArray outputData = ffmpegProcess.readAllStandardOutput();
        // 在这里你可以对 outputData 进行处理,比如保存为文件或传递给其他模块进行处理
    } else {
        // 进程未能正常完成
        qDebug() << "转码失败:" << ffmpegProcess.errorString();
    }

    return a.exec();
}

注意事项

在上面的示例中,我们将 FFmpeg 的输出格式设置为 matroska,并通过管道获取转码后的视频流。转码后的视频流将保存在 outputData 变量中。你可以根据需要对视频流进行处理,例如保存为文件或传递给其他模块进行进一步处理。

请注意,如果视频非常大,或者转码过程非常耗时,可能会导致 readAllStandardOutput() 方法阻塞程序。为了避免阻塞,你可以使用 readyReadStandardOutput() 信号来异步读取输出流的数据,或者使用其他方法逐块读取数据。

关于readAllStandardOutput() 和 readyReadStandardOutput()介绍

readAllStandardOutput() 方法:

QByteArray readAllStandardOutput(): 该方法会读取并返回子进程的标准输出(stdout)中的所有数据。
调用该方法会阻塞当前线程,直到子进程完成并关闭了标准输出通道,或者直到 QProcess 对象被销毁为止。
如果子进程的输出量较小,且处理速度较快,使用该方法可能是方便的。它将一次性返回所有输出数据,你可以直接对数据进行处理。
然而,如果子进程的输出较大,或者处理速度较慢,使用该方法可能会导致主线程阻塞,造成程序无响应的情况。因此,在处理大量输出数据或子进程输出速度较快时,推荐使用 readyReadStandardOutput() 方法。
readyReadStandardOutput() 信号:

信号声明:void readyReadStandardOutput()
该信号会在子进程的标准输出通道有新数据可读取时触发,表示可以安全地读取数据而不会阻塞主线程。
当你启动子进程后,并希望异步处理其输出数据时,可以连接该信号到槽函数来处理。每次该信号触发时,都可以调用 readAllStandardOutput() 或 readLineStandardOutput() 方法来读取新的输出数据。
注意:由于该信号在子进程输出可读取时会频繁触发,因此你应该在槽函数中高效地处理数据,并避免耗时操作,以免影响程序的响应性能。

例子:

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 创建一个 QProcess 对象
    QProcess ffmpegProcess;

    // 设置要执行的外部命令和参数...
    // (与之前示例相同)

    // 设置标准输出读取通道
    ffmpegProcess.setReadChannel(QProcess::StandardOutput);

    // 连接 readyReadStandardOutput() 信号到槽函数
    QObject::connect(&ffmpegProcess, &QProcess::readyReadStandardOutput, [&ffmpegProcess](){
        // 读取并处理输出数据
        QByteArray outputData = ffmpegProcess.readAllStandardOutput();
        // 在这里你可以对 outputData 进行处理,比如保存为文件或传递给其他模块进行处理
    });

    // 启动外部进程
    ffmpegProcess.start(program, arguments);

    // ...

    return a.exec();
}

总结:readAllStandardOutput() 方法适合处理较小量的输出数据,或者在子进程完成后读取所有输出;而 readyReadStandardOutput() 信号适用于异步处理输出数据,特别是在输出数据量较大或输出速度较快的情况下,避免阻塞主线程。根据实际场景,你可以选择使用其中的一种或两种方法来处理子进程的标准输出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT中使用 QProcess接口 执行 fmmpeg命令,实现简单的音视频处理 的相关文章

  • QMessageBox::about 可以根据标题长度调整大小吗?

    我想创建一个简单的 关于 对话框 但注意到QMessageBox about不会根据标题的长度调整其大小 由于字体较大 标题通常会更长 至少在我的桌面环境中 仅根据内容调整其大小 有没有办法确保对话框足够大以显示所有标题 我当然可以向 ab
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • 如何在服务器上使用 ffmpeg 从 WebRTC 流获取音频和视频

    我正在尝试从 WebRTC 流获取音频和视频 并在 ubuntu 服务器上使用 ffmpeg 处理它 转码或转储 我天真地期望它能简单地解释 WebRTC 提供的 sdp 但我错了 我怀疑 ffmpeg 无法发回答案 sdp 必须手动完成
  • 在 Windows 上从源代码构建 PhantomJS-2

    我正在尝试基于这些在 Windows 8 1 x64 上从源代码构建 PhantomJS 2 的开发版本指示 https github com ariya phantomjs wiki PhantomJS 2 但是我收到以下错误 mingw
  • 如何重写(重新实现)QFileSystemModel 中的成员函数

    我已经为此苦苦挣扎了一段时间 Qt s QFileSystemModel由于图标获取算法非常糟糕 在获取数百个文件时速度非常慢 我想完全禁用图标 它们被提取到QFileSystemModel data方法不是虚拟的 QFileSystemM
  • MSVC C4100:“应用程序”:未引用的形式参数警告

    使用 MSVC 编译时 以下代码会生成 C4100 警告 这怎么可能 显然引用了 应用程序 class ApplicationInfo public QObject Q OBJECT public static void initializ
  • 如何通过信号和槽传递参数?

    我的 GUI 包括LineEdit and a 按钮 当 的时候按钮单击后 插槽clicked 叫做 我想在之间建立信号槽关系clicked 作为信号和doSomething 作为插槽 问题是doSomething 无权访问 UI 并且do
  • 如何从键盘为 QTableWidget 创建信号?

    我有一张桌子 可以通过左 右 上 下按钮在里面移动 现在 当我停留在某个单元格并按空格键时 我需要创建一个信号 该信号还应该带来该单元格的坐标 我尝试使用 QTableWidget 的标准信号 但它不起作用 我该如何解决这个问题 创建一个单
  • Qt - QProcess 不工作

    我尝试启动 Internet Explorer 所以我使用下面的代码 QProcess process new QProcess this QString temp C Program Files Internet Explorer iex
  • Qt - 意外的 GDB 退出

    我正在尝试开发一个应用程序 该应用程序创建图像并使用双线性插值填充颜色像素 然后显示它 到目前为止我的代码如下 include
  • Qt:关闭期间线程仍在运行时 qthread 被销毁

    我有一堂课 class centralDataPool public QObject Q OBJECT public centralDataPool QObject parent 0 centralDataPool commMonitor
  • Qt QML MenuItem iconSource不显示

    我有一个非常简单的设置只是为了说明问题 import QtQuick Controls 1 4 import QtQuick Window 2 2 ApplicationWindow visible true width 640 heigh
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • 使用 QPrinter 打印第 x 页(共 y 页)

    我使用 qt 从 html 代码生成 pdf 文件 QTextDocument document new QTextDocument document gt setHtml htmlContent QPrinter printer QPri
  • QGraphicsView 在完整布局中未最大化

    I have following GUI having four QGraphicView objects 正如您在每个视图下看到的那样 它有四个工具按钮 为了最大化视图 我连接了工具按钮的信号来隐藏其他三个视图的插槽 并将大小策略设置为扩
  • 如何使用 ffmpeg av_seek_frame() 在具有帧号的情况下读取任何帧

    int64 t timeBase timeBase int64 t pavStrm gt time base num AV TIME BASE int64 t pavStrm gt time base den int64 t seekTar
  • 在 Qt 中构建 Android 项目不再有效

    所以我对 Android SDK NDK 和 Apache Ant 进行了一些更新 现在我无法构建任何 Android 项目 我收到一条警告 然后它说找不到 build xml 文件 错误 Warning Android platform
  • 将循环视频添加到声音 ffmpeg

    我开始使用 ffmpeg 这是我的第一个疑问 我有一个声音文件 example mp3 持续时间 1 分钟 我想添加一个循环视频 example mp4 x 秒持续时间 在这种情况下 我想生成 1 分钟的 mp4 视频并循环该视频 3 次
  • 有没有更有效的方法通过ffmpeg批量添加水印和加入视频?

    我有这个批处理文件 使用 ffmpeg 在我的视频中添加徽标 然后添加简介 但需要 10 小时到一天的时间 具体取决于我需要添加水印的数量 是否有更有效的方法来实现此目的 视频有时具有不同的分辨率 因此我无法删除到 1280 720 尺寸的
  • PyQt QFileDialog exec_ 很慢

    我正在使用自定义QFileDialog因为我想选择多个目录 但是exec 功能非常慢 我不明白为什么 我正在使用最新版本的 PyQt 代码片段 from PyQt4 import QtGui QtCore QtNetwork uic cla

随机推荐

  • 【Linux篇】fputs、fgets函数

    一 fputs函数 include
  • 水下图像采集

    原文 http blog csdn net sunlinyi66 article details 50153875 NASA提供的雾天标准图像 这次终于找到了雾天处理图像来自哪里了 雾天图像 http dragon larc nasa go
  • 机器学习——朴素贝叶斯算法

    朴素贝叶斯算法 1 引言 2 朴素贝叶斯分类方法 3 概率基础 4 朴素贝叶斯特征提取 5 朴素贝叶斯分类的sklearn实现 6 垃圾短息分类 补充 1 引言 贝叶斯方法是一个历史悠久 有着坚实的理论基础的方法 同时处理很多问题时直接而又
  • django自动生成接口文档

    django自动生成接口文档 先pip安装coreapi包 配置 在urls py 在对应的serializers py文件设置备注 先pip安装coreapi包 pip install coreapi 小知识 这里不需要使用 导出pip所
  • 亚马逊云服务器aws配置ssl https证书

    文章目录 1 申请证书 1 1 搜索ssl 1 2 请求证书 1 3 请求共有证书 1 4 添加域名 1 5 选择验证方法 提交审核 等待大概10分钟 审核成功 2 配置证书 2 1 创建负载均衡器 2 2 选择https 2 3 配置负载
  • Qt创建一个自定义按钮

    1 概述 案例 编写一个自定义按钮 要求 1 给按钮添加自定义背景 2 监听按钮点击事件 2 代码案例 1 创建一个类让其继承QWidget 点击下一步下一步最后完成 2 打开MyPushButton 让其继承QPushButton 如下所
  • java 子线程 异常_Java子线程中的异常处理(通用)

    在普通的单线程程序中 捕获异常只需要通过try catch finally 代码块就可以了 那么 在并发情况下 比如在父线程中启动了子线程 如何在父线程中捕获来自子线程的异常 从而进行相应的处理呢 常见错误 也许有人会觉得 很简单嘛 直接在
  • 【数据结构】Binary Search Tree(BST) 二分搜索树

    数据结构源码 实现类 import java util import java util LinkedList import java util Queue import java util Stack 二分搜素树 BST param
  • Cannot resolve com.sun:tools:1.8

    问题描述 使用druid编译的时候说找不到这个包 解决过程 首先定位原因 通过pom可以找到对应的位置 报的是这个包找到不到 于是我也尝试着更换openjdk 但是还是不行 这两个包是在jdk当中的lib目录下 针对于这个问题一共有4个处理
  • 第十八天---IPV6

    链路聚合 可以将多个物理接口捆绑成一个逻辑接口 即将N条物理链路聚合为一条逻辑链路 可以在不升级硬件的条件下 达到增加带宽的效果 我们将逻辑链路 称为聚合链路 在华为设备中称为ETH TRUNK链路 这个技术是针对以太网技术设计的 我们将每
  • C语言-编译过程与内存分配

    一 编译过程 1 预编译 预处理 预处理过程实质上是处理 将 include包含的头文件直接拷贝到hell c当中 将 define定义的宏进行替换 同时将代码中没用的注释部分删除等 具体做的事儿如下 1 将所有的 define删除 并且展
  • 09 插件开发快速入门

    V5标准架构模型 V5平台基于三层模型开发 下面是相关架构图 建议认真阅读业务流向 入门 字符集 为了实现国际化编程 全局要求使用UTF 8的字符集编码 包括 数据库 参考安装维护手册配置字符集 文件 java properties jsp
  • Linux命令基础

    一 Linux命令新手 cd 意思是到上一级目录 cd 意思是返回到上次的目录 类似windows返回 cd 意思是回到根目录 1 增 使用mkdir 命令创建文件夹 先使用命令 cd home 意思是打开home目录 再使用命令 ls 意
  • oracle数据库 创建用户 并授权访问

    oracle数据库 创建用户 并授权访问 create user USER TEST 1 identified by USER TEST 1 创建用户 设置密码 grant connect to USER TEST 1 授权 连接 gran
  • 零经验也可以入职大厂吗,毕业生的第一份实习如何成功逆袭?

    很多小伙伴在找实习的时候都遇到了一个拷问灵魂深处的问题 第一次找实习 面试官嫌弃没有相关经验 应该怎么办 不管是刚回国的留学生还是没有经验的大二大三在校学生 在找实习的时候 很多企业连一个 第一次 的机会都不会给 在筛选简历时直接pass掉
  • Android实现支付宝支付遇到的问题记录--主要是和服务器的合作上

    一 已解决 1 客户端需要处理的很简单 跟服务器接口要带有签名的商品信息 即支付宝api需要的入参 2 服务器的联合排查工作 由于服务器工作较忙 需要联合定位 且自己对php不了解 过程比较头疼和耗时 主要出现两个问题 1 ALI64 解决
  • IOS开发笔记 - 基于wsdl2objc调用webservice

    为了方便在ios下调用webserivce 找来了wsdl2objc这样一个开源的框架来解析webservice方便在ios下引用 下面做个小例子 1 首先是用Asp net搭建一个测试的webserivce并放在IIS服务器上面 核心代码
  • Android篇——使用第三方视频框架GSYVideoPlayer时,报错:the sensor listeners size has exceeded the maximum limit 128

    背景 在列表 ListView RecyclerView 中使用GSYVideoPlayer播放视频时 闪退报错the sensor listeners size has exceeded the maximum limit 128 原因是
  • MySQL基础篇--自用笔记

    MySQL基础篇 数据库相关概念 名称 全称 简称 数据库 存储数据的仓库 数据是有组织的进行存储 DataBase DB 数据库管理系统 操纵和管理数据库的大型软件 DataBase Management System DBMS SQL
  • QT中使用 QProcess接口 执行 fmmpeg命令,实现简单的音视频处理

    QProcess 介绍 QProcess 是 Qt 框架中用于启动外部进程和与之进行交互的类 它提供了一个方便的接口 允许你执行外部命令并捕获其输出 错误信息以及监控其运行状态 通过使用 QProcess 类 你可以在你的 Qt 应用程序中