我如何通过ffmpeg将Node.js中生成的画布流式传输到youtube /其他rtmp服务器?

如何解决我如何通过ffmpeg将Node.js中生成的画布流式传输到youtube /其他rtmp服务器?

我想在Node.JS中生成一些图像,将它们编译为视频并将其流式传输到youtube。为了生成图像,我正在使用节点画布模块。这听起来很简单,但是我想连续生成图像,并实时传输结果。我对这件事很陌生,在阅读互联网上的大量资源后,我正在考虑做的事情是:

  1. 使用spawn('ffmpeg',...args)打开ffmpeg,将输出设置为目标rtmp服务器
  2. 在画布上生成图像
  3. 将画布的内容转换为缓冲区,然后通过stdin将其写入ffmpeg进程
  4. 在YouTube上享受结果

但这不是那么简单,是吗?我看到人们共享他们的代码,这些代码涉及在浏览器上运行的客户端JS,但是我希望它成为Node应用程序,以便可以从远程VPS运行它。 有没有办法在我的浏览器中不使用p5之类的东西并捕获窗口以进行重播而做到这一点? 我的思考过程是否足够恰当?现在,我并不真的在乎性能/资源的使用。预先感谢。

编辑:

我花了一些时间,但我无法使它工作... 这是我的代码

const { spawn } = require('child_process');
const { createCanvas } = require('canvas');
const fs = require('fs');


const canvas = createCanvas(1920,1080);
const ctx = canvas.getContext('2d');
const ffmpeg = spawn("ffmpeg",["-re","-f","png_pipe","-vcodec","png","-i","pipe:0","h264","-re","flv","rtmp://a.rtmp.youtube.com/live2/key-i-think"],{ stdio: 'pipe' })

const randomColor = (depth) => Math.floor(Math.random() * depth)
const random = (min,max) => (Math.random() * (max - min)) + min;

let i = 0;
let drawSomething = function () {
    ctx.strokeStyle = `rgb(${randomColor(255)},${randomColor(255)},${randomColor(255)})`
    let x1 = random(0,canvas.width);
    let x2 = random(0,canvas.width);
    let y1 = random(0,canvas.height);
    let y2 = random(0,canvas.height);
    ctx.moveto(x1,y1);
    ctx.lineto(x2,y2);
    ctx.stroke();

    let out = canvas.toBuffer();
    ffmpeg.stdin.write(out)
    i++;
    if (i >= 30) {
        ffmpeg.stdin.end();
        clearInterval(int)
    };
}

drawSomething();
let int = setInterval(drawSomething,1000);

我没有任何错误,也没有从中获取任何视频数据。我已经设置了一个可以连接到的rtmp服务器,然后使用VLC获取流,但是我没有任何视频数据。难道我做错了什么?我环顾了一会儿,似乎找不到任何尝试过此方法的人,所以我真的没有任何线索...

编辑2: 显然我在正确的轨道上,但是我的方法只是给了我2秒钟的“好”视频,然后开始变得块状且混乱。我认为最有可能的是,我生成图像的方法太慢了。我将尝试使用一些GPU加速代码生成图像,而不是使用画布,这意味着我将一直在进行分形,因为我不知道该怎么做。另外,在ffmpeg中使用更大的缓冲区也可能有帮助

解决方法

您的方法很好。请记住,无论您流向何处,都将期望源端跟上潮流。如果您不能足够快地生成帧,那么各种各样的事情都会出错。 (我认为这主要是由于YouTube试图丢弃太慢的信号源,并在接收到帧后再次进行拾取,只是再次失败了。)

您可以通过在尝试流式传输到RTMP服务器之前先输出到文件来进行测试。

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

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?