I am trying to stream to twitch from a Node.js script for fun! so far i have got it working but its slow and seemingly limited to 10-12 fps.
Here is my code, i am trying to stream a Node-Canvas to twitch so i can do stuff without the overhead of OBS and in a console:
import { createCanvas } from 'canvas';
import { spawn } from 'child_process'
import fs from 'fs';
const canvas = createCanvas(1920, 1080);
const ctx = canvas.getContext('2d');
// create a ffmpeg process that will stream the canvas to a rtmp server
const ffmpeg = spawn('ffmpeg', [
'-re', // read input at native frame rate
'-f', 'image2pipe', // tell ffmpeg to expect raw image stream
'-vcodec', 'png', // tell ffmpeg to expect jpeg encoded images
'-r', '10', // tell ffmpeg to expect 60 fps
'-s', '1920x1080', // tell ffmpeg to expect size 1920x1080
'-i', '-', // tell ffmpeg to expect input from stdin
//'-c:v', 'h264_amf', // tell ffmpeg to encode in h264 codec AMD
'-c:v', 'libx264', // tell ffmpeg to encode in h264 codec
'-pix_fmt', 'yuv420p', // tell ffmpeg to encode in yuv420p format
'-preset', 'ultrafast', // tell ffmpeg to use ultrafast encoding preset
'-g', '20', // set the keyframe interval to 2 seconds so twitch will not reject the stream
'-f', 'flv', // tell ffmpeg that we are going to stream flv video
"rtmp://live.restream.io/live/"
]);
ffmpeg.on('close', (code, signal) => {
console.log('FFmpeg child process closed, code ' + code + ', signal ' + signal);
})
ffmpeg.on('error', (err) => {
console.log('FFmpeg child process error: ' + err.message);
})
ffmpeg.stderr.on('data', (data) => {
//console.log('FFmpeg stderr: ' + data);
//ParseFFPMPEGOutput(data.toString());
})
ffmpeg.stdout.on('data', (data) => {
console.log('FFmpeg stdout: ' + data);
})
var DrawingCatagorys: string[] = []
fs.readFileSync('categories.txt').toString().split('\n').forEach(function (line) { DrawingCatagorys.push(line); })
function ParseFFPMPEGOutput(data: string) {
if (data.includes('frame=')) {
let frame = data.split('frame=')[1].split('fps')[0].trim();
let fps = data.split('fps=')[1].split('q=')[0].trim();
let size = data.split('size=')[1].split('time=')[0].trim();
let time = data.split('time=')[1].split('bitrate=')[0].trim();
let bitrate = data.split('bitrate=')[1].split('speed=')[0].trim();
console.log(`Frame: ${frame} FPS: ${fps} Size: ${size} Time: ${time} Bitrate: ${bitrate}`);
}
}
// create a png stream
setInterval(() => {
// convert canvas to png
const buffer = canvas.toBuffer('image/png');
// write png stream to stdin of ffmpeg process
ffmpeg.stdin.write(buffer);
}, 2);
Im thinking it has to do with Node-Canvas just being slow but i have no idea, also even on my gaming rig it cant pull 1x speed while streaming always sitting around 0.95 - 0.98 and about 9.2 fps. also it only works on chrome and not firefox? i have no idea why probably a codec thing