Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
@api.video/browser-to-rtmp-server
Advanced tools
Library to broadcast the stream of a webcam from the browser to an RTMP server (server part).
api.video is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managing on-demand & low latency live streaming features in your app.
WARNING: this project is still in beta version. Use it with care and do not hesitate to report any problem you may encounter.
This project aims to make easy streaming a video from your browser to a RTMP server. Any MediaSource can be used (webcam, screencast, …).
The project is composed of three npm workspaces:
First make sure that ffmpeg
is properly installed on your server.
Then add the dependancy to your nodejs project:
npm install --save @api.video/browser-to-rtmp-server
You can finally instanciate the server:
import http from 'http';
import BrowserToRtmpServer from '@api.video/browser-to-rtmp-server';
// ...
const server = http.createServer();
const browserToRtmpClient = new BrowserToRtmpServer(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
credentials: true
}
});
server.listen(1234);
<html>
<head>
...
<script src="https://unpkg.com/@api.video/browser-to-rtmp-client" defer></script>
</head>
<body>
<script>
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then((stream) => {
const client = new BrowserToRtmpClient(stream, {
host: "localhost",
rtmpUrl: "rtmp://0.0.0.0:1935/s/abcd", // RTMP endpoint
port: 1234
});
client.start();
});
</script>
</body>
</html>
Unfortunately, the browser cannot communicate directly with an RTMP server (due to network restrictions inherent in web browsers).
To overcome this problem, we added a layer between the browser and the RTMP server. It is a nodejs server that has the task of transforming a websocket video stream from the browser to an RTMP stream.
This mechanism is summarized in the following diagram:
The BrowserToRtmpServer
constructor takes 2 parameters:
http.Server
(the server that will handle the WebSocket connections)BrowserToRtmpServerOptions
(an object that contains the options of the instance to create)Leaving it up to the developer to provide an http server provides great flexibility. You can for example decide to use https instead of http with a code like this:
import fs from "fs";
import https from "https";
import BrowserToRtmpServer from '@api.video/browser-to-rtmp-server';
const httpsServer = https.createServer({
key: fs.readFileSync("/tmp/key.pem"),
cert: fs.readFileSync("/tmp/cert.pem")
});
const options = { /* ... */ }; // BrowserToRtmpServerOptions
const browserToRtmpServer = new BrowserToRtmpServer(httpsServer, options);
httpsServer.listen(3000);
The BrowserToRtmpServerOptions has the following attributes:
{
serverLogs?: {
minLevel?: 'silly' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; // log level (default: info)
}
clientLogs?: {
sendErrorDetails?: boolean, // weither detailed error messages should be sent to the client or not (default: false)
sendFfmpegOutput?: boolean, // weither ffmpeg output should be sent to the client or not (default: false)
}
maxFfmpegInstances?: number; // the maximum number of ffmpeg instances that can be run in parallel (if this limit is reached, connections will be refused) (default: empty, ie no limit)
rtmpUrlRegexp?: RegExp; // the template of allowed rtmp endpoints, in the form of a regular expression (example: /https:\/\/rtmp:\/\/broadcast.api.video\/s\/.*/, default: empty)
socketio?: Partial<ServerOptions>, // socket.io options (see https://socket.io/docs/v4/server-options/)
hooks?: {
// a function that will be called each time a client starts a livestream, can be use to override the livestream settings sent by the client (see bellow)
start?: (socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>, event: FfmpegConfig) => FfmpegConfig;
}
}
All settings sent from the client when starting the livestream can be overwritten server-side using the hooks.start
hook. For instance, the client can omit prividing the RTMP endpoint, leaving the server part filling it:
const browserToRtmpServer = new BrowserToRtmpServer(server, {
// ...
hooks: {
start: (socket, config) => {
// for instance, you can here access the socket associated to the current request:
// const token = socket.handshake.auth.token; // retrieve the auth token
// ...
const rtmpEndpoint = "rtmp://0.0.0.0:1234/s/abcd" // you can generate here the RTMP endpoint url according to your need:
return {
...config,
rtmp: rtmpEndpoint
}
}
}
});
getConnections()
Retrieve the list of all active connections. It returns a list of ConnectionStatus
:
{
uuid: string; // unique identifier for the connection
remoteAddress: string; // remote ip address
ffmpeg?: { // details about the ffmpeg instance associated to the connection (can be undefined if ffmpeg is not yet running or if it has stopped)
status: 'RUNNING' | 'ENDED' | 'ENDING' | 'CREATED'; // ffmpeg status
framesSent: number; // number of frame that has been sent to the RTMP server
lastFrameSentTime?: number; // timestamp of the last sent frame
pid?: number; // pid of the ffmpeg process
options: { // options that has been used to start ffmpeg
framerate?: number;
audioSampleRate?: number;
rtmp?: string;
audioBitsPerSecond?: number;
videoBitsPerSecond?: number;
}
}
}
You can listen to events that emitted are by using the on(eventName: string)
method.
connection
eventThe connection
event is sent each time a new connection arrives. It contains the connection status associated to the connection.
Example:
browserToRtmpServer.on("connection", (c) => {
console.log(`New connection uuid: ${c.uuid}`);
});
ffmpegOutput
eventThis event is sent each time one of the ffmpeg instances write something to its output stream. It contains the uuid of the connection and the output message itself.
Example:
browserToRtmpServer.on("ffmpegOutput", (uuid, message) => {
console.log(`Ffmpeg output for connection ${uuid}: ${message}`);
});
error
eventThis event is sent each time a error occurs for a given connection. It contains the uuid of the connection and the error.
Example:
browserToRtmpServer.on("error", (uuid, error) => {
console.log(`Error for connection ${uuid}: ${message}`);
});
rtmpUrlRegexp
, or generate the url from the server with the start hook, as explained before.The BrowserToRtmpServer
constructor takes 2 parameters:
navigator.mediaDevices.getDisplayMedia()
or navigator.mediaDevices.getUserMedia()
)BrowserToRtmpClientOptions
(an object that contains the options of the instance to create)The BrowserToRtmpClientOptions has the following attributes:
type BrowserToRtmpClientOptions = {
host: string; // host of the server where your BrowserToRtmpServer is waiting for connections
port?: number; // the port associated to the server (default: 8086)
framerate?: number; // the framerate (default: 25)
rtmp?: string; // the RTMP endpoint url (if not providded, it has to be set server-side)
audioBitsPerSecond?: number; // audio bits per second (default: 128000)
videoBitsPerSecond?: number; // video bits per second (default: 2500000)
audioSampleRate?: number; // the sample rate for audio (default: audioBitsPerSecond / 4)
socketio?: Partial<ManagerOptions & SocketOptions>; // socket.io client options (see https://socket.io/docs/v4/client-options/)
}
You can listen to events that emitted are by using the on(eventName: string)
method.
error
eventThe error
event is sent each time an error occured. It contains the error itself.
Example:
browserToRtmpClient.on("error", (error) => {
console.log(`An error occured: ${error}`);
});
destroyed
eventThe destroyed
event is sent when the ffmpeg instance associated to the connection is destroyed.
Example:
browserToRtmpClient.on("destroyed", (error) => {
console.log(`Instance destroyed`);
});
ffmpegOutput
eventThis event is sent each time the ffmpeg instance write something to its output stream. The event is sent only if the clientLogs.sendFfmpegOutput
param is true on the server side.
Example:
browserToRtmpClient.on("ffmpegOutput", (message) => {
console.log(`Ffmpeg output: ${message}`);
});
start()
Start the stream.
pause()
Pause the stream.
stop()
Stop the stream.
FAQs
Library to broadcast the stream of a webcam from the browser to an RTMP server (server part).
We found that @api.video/browser-to-rtmp-server demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.