使用 boost 将 ffmpeg 输出传送到 ffplay stdin

如何解决使用 boost 将 ffmpeg 输出传送到 ffplay stdin

我正在尝试将 ffmpeg 进程的输出通过管道传输到 ffplay 进程(有点像播放)。我的问题如下:如果我逐个字符地复制输出(逐个字符我的意思是 import re re.search("(?<=\t).*?(?=\t)",s)[0] # Output: "John" ),它可以正常工作,除了消耗大量 CPU 功率。但是,当我尝试将块通过管道传输到其中时(通过使用缓冲区),ffplay 由于某种原因甚至无法识别输入。

char

以下是用于比较的 2 个代码片段:

这里是通过bp::ipstream iso; bp::ipstream ise; bp::opstream in; bp::child ffmpeg(bp::search_path("ffmpeg"),bp::args({"-loglevel","quiet","-f","pulse","-i","default","wav","-bitexact","-nostdin","-"}),bp::std_out > iso,bp::std_err > ise); bp::child ffplay(bp::search_path("ffplay"),"verbose","-nodisp",bp::std_in < in,bp::std_out > bp::null); 复制char

char

这里是在缓冲区的帮助下进行复制

while(ffmpeg.running()) {
    char c;
    c = iso.get();
    in << c;
}

如有必要,我可以提供 ffplay 输出,但是我没有看到任何错误或类似的东西。

解决方法

无需手动执行繁琐的工作,您只需连接相同的管道即可:

bp::child ffmpeg(
    pg,bp::search_path(prod.cmd),bp::args(prod.args),bp::std_out > iso,bp::std_err > ise
);

bp::child ffplay(
    pg,bp::search_path(cons.cmd),bp::args(cons.args),(bp::std_in < iso)
    //,(bp::std_out> bp::null)
);

这将满足您的期望。这也意味着您不要选择 ipstream/opstream,因为角色是两者:

//bp::pstream iso,ise,in;
bp::pipe iso,in;

两者都有效,但您可能不需要流对象的复杂性。事实上,您可以使用异步版本,它的行为仍然相同(但为异步运行提供更多选项/控制):

enter image description here

在线演示

明显替换/简化了生产者/消费者进程的命令:

Live On Coliru

#include <boost/process.hpp>

namespace bp = boost::process;
using namespace std::chrono_literals;
using boost::system::error_code;

int main() {
    //bp::pstream iso,in;
    bp::pipe iso,in;
    //boost::asio::io_context io;
    //bp::async_pipe iso(io),ise(io),in(io);
    bp::group pg;

    struct { std::string cmd; std::vector<std::string> args; } tasks[] = {
#if 1
         { "bash",{ "-c","echo 'hello world'"} },{ "rev",{} },#else
         { "ffmpeg",{"-loglevel","quiet","-f","pulse","-i","default","wav",/*"-bitexact",*/ "-nostdin","-"} },{ "ffplay","verbose","-nodisp",#endif
    };

    auto& [prod,cons] = tasks;

    bp::child ffmpeg(
        pg,bp::std_err > ise
    );

    bp::child ffplay(
        pg,(bp::std_in < iso)
        //,(bp::std_out> bp::null)
    );

    if (!pg.wait_for(4s))
        pg.terminate();
}

按预期打印“hello world”的反面:

dlrow olleh

做坏事

只是为了说明,这里是您如何手动执行 IO 泵。

Live On Coliru

#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <iostream>

namespace bp = boost::process;
using namespace std::chrono_literals;
using boost::system::error_code;

int main() {
    //bp::pstream iso,in;
    //bp::pipe iso,in;
    boost::asio::io_context io;
    bp::async_pipe iso(io),"echo -e 'hello world\\nYOHOHO\\nMOHOHO\\n'"} },{ "xxd",cons] = tasks;

    bp::child ffmpeg(
        io,pg,bp::std_err > ise
    );

    bp::child ffplay(
        io,(bp::std_in < in)
        //,(bp::std_out> bp::null)
    );

    std::function<void()> stream_pump;
    stream_pump = [&,buf=std::vector<char>(1024)]() mutable {
      boost::asio::async_read(iso,boost::asio::buffer(buf),[&](error_code ec,size_t const nread) {
        bool const eof = (ec == boost::asio::error::eof);
        std::cerr << "nread: " << nread << " (eof:" << eof << ")\n";
        if (ec && !eof)
          std::cerr << "async_read: " << ec.message() << " (" << nread << ")\n";
        else
          boost::asio::async_write(in,boost::asio::buffer(buf,nread),[=,&in,&stream_pump](error_code ec,size_t /*nwritten*/) {
              if (ec || eof) {
                std::cerr << "Closing in\n";
                in.close();
              }
              else
                stream_pump(); // continue the pump
          });
      });
    };

    stream_pump(); // prime the pump

    auto nhandlers = io.run_for(4s);
    std::cerr << "Handlers executed: " << nhandlers << "\n";
    ffmpeg.terminate();

    if (ffplay.running())
        ffplay.wait_for(1s);

    if (ffplay.running())
        pg.terminate();
}

印刷品

nread: 27 (eof:1)
Closing in
Handlers executed: 6

消费者子进程标准输出包含

00000000: 6865 6c6c 6f20 776f 726c 640a 594f 484f  hello world.YOHO
00000010: 484f 0a4d 4f48 4f48 4f0a 0a              HO.MOHOHO..

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res