Ref : https://www.mux.com/blog/the-state-of-going-live-from-a-browser
The above blog states my problem in detail and presented a solution also. I am trying to implement the solution which is using socketio
Here is the description of the problem :
I want to capture the video and audio from the browser using
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
and i am using the
const options = {
mimeType: "video/webm;codecs=vp8",
};
const mediaRecorder = new MediaRecorder(stream, options);
to record the video chunk by chunk from the stream given by getusermedia and then using the socket io to send the video to the backend. Where I am using the ffmpeg to stream the chunks on rtmp url.
I am using the following ffmpeg commands :
const { spawn } = require('child_process');
const ffmpegProcess = spawn('ffmpeg', [
'-i', 'pipe:0',
'-c:v', 'libx264',
'-preset', 'veryfast',
'-tune', 'zerolatency',
'-c:a', 'aac',
'-ar', '44100',
'-f', 'flv',
rtmpurl
]);
And I am getting the following errors:
Can anyone help me how to fix this. I am new to FFmpeg.
Here is the complete frontend and Backend code :
Frontend (App.jsx) :
import { useEffect } from "react";
import "./App.css";
import io from "socket.io-client";
function App() {
let video;
useEffect(() => {
video = document.getElementById("video");
}, []);
const socket = io("http://localhost:3050");
socket.on("connect", () => {
console.log("Connected to server");
});
let stream;
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((strea) => {
video.srcObject = strea;
stream = strea;
const options = {
mimeType: "video/webm;codecs=vp8",
};
const mediaRecorder = new MediaRecorder(stream, options);
console.log(mediaRecorder);
let chunks = [];
mediaRecorder.ondataavailable = function (e) {
chunks.push(e.data);
console.log(e.data);
};
mediaRecorder.onstop = function (e) {
const blob = new Blob(chunks, { type: "video/webm;codecs=vp8" });
console.log("emitted");
socket.emit("videoChunk", blob);
chunks = [];
// const videoURL = URL.createObjectURL(blob);
// const a = document.createElement('a');
// a.href = videoURL;
// a.download = 'video.mp4';
// a.click();
window.URL.revokeObjectURL(videoURL);
};
mediaRecorder.start();
setInterval(() => {
mediaRecorder.stop();
mediaRecorder.start();
}, 2000);
})
.catch((error) => {
console.error("Error accessing camera:", error);
});
// Capture video after 10 seconds
return (
<>
<video id="video" width="640" height="480" autoPlay></video>
<button id="captureButton">Capture</button>
</>
);
}
export default App;
Backend Code :
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const { spawn } = require('child_process');
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}, maxhttpBufferSize: 1e8
});
const rtmpurl = 'rtmp://localhost/live/test';
io.on('connection', (socket) => {
console.log('A user connected');
const ffmpegProcess = spawn('ffmpeg', [
'-i', 'pipe:0',
'-c:v', 'libx264',
'-preset', 'veryfast',
'-tune', 'zerolatency',
'-c:a', 'aac',
'-ar', '44100',
'-f', 'flv',
rtmpurl
]);
ffmpegProcess.stdin.on('error', (e) => {
console.log(e);
});
ffmpegProcess.stderr.on('data', (data) => {
console.log(data.toString());
});
ffmpegProcess.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
socket.on('videoChunk', (chunk) => {
console.log(chunk)
ffmpegProcess.stdin.write(chunk);
});
socket.on('disconnect', () => {
console.log('User disconnected');
ffmpegProcess.stdin.end();
});
});
const PORT = process.env.PORT || 3050;
app.get('/test', (req, res) => {
res.send('Hello from /test route!');
});
server.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});