如何在网络浏览器中使用 GStreamer 的 webrtcbin?
How to use GStreamer's webrtcbin with a web browser?
在线有很多示例将 GStreamer 管道与“tcpclientsink”或“udpsink”与 NodeJS 一起使用,以使用 GStreamer 管道输出到 Web 浏览器。
但我找不到任何示例或文档来清楚地解释如何将 webrtcbin 管道与 NodeJS 服务器一起使用以将流发送到 Web 浏览器。
我有以下 GStreamer 管道:
gst-launch-1.0 videotestsrc \
! queue ! vp8enc ! rtpvp8pay \
! application/x-rtp,media=video,encoding-name=VP8,payload=96 \
! webrtcbin name=sendrecv
有人可以帮助使用基于 NodeJS 的服务器使用此管道以在 Web 浏览器上显示流吗?
这是一个类似的例子,但它使用了 tcpclientsink
:
https://tewarid.github.io/2011/04/26/stream-live-webm-video-to-browser-using-node.js-and-gstreamer.html
不幸的是,事情并没有那么简单。您必须有某种方式与浏览器交互才能交换 SDP offer/answer,以及 ICE 候选人交换。
你可以看例子here
更新:
最后,我能够使用问题中提到的 NodeJS 教程实现 GStreamer 到浏览器。这是一个概念验证代码,如果需要(或者在教程 link 从互联网上删除的情况下),有人可以使用它:
var express = require('express')
var http = require('http')
var net = require('net');
var child = require('child_process');
require('log-timestamp'); //adds timestamp in console.log()
var app = express();
app.use(express.static(__dirname + '/'));
var httpServer = http.createServer(app);
const port = 9001; //change port number is required
//send the html page which holds the video tag
app.get('/', function (req, res) {
res.send('index.html');
});
//stop the connection
app.post('/stop', function (req, res) {
console.log('Connection closed using /stop endpoint.');
if (gstMuxer != undefined) {
gstMuxer.kill(); //killing GStreamer Pipeline
console.log(`After gstkill in connection`);
}
gstMuxer = undefined;
res.end();
});
//send the video stream
app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type': 'video/webm',
});
var tcpServer = net.createServer(function (socket) {
socket.on('data', function (data) {
res.write(data);
});
socket.on('close', function (had_error) {
console.log('Socket closed.');
res.end();
});
});
tcpServer.maxConnections = 1;
tcpServer.listen(function () {
console.log("Connection started.");
if (gstMuxer == undefined) {
console.log("inside gstMuxer == undefined");
var cmd = 'gst-launch-1.0';
var args = getGstPipelineArguments(this);
var gstMuxer = child.spawn(cmd, args);
gstMuxer.stderr.on('data', onSpawnError);
gstMuxer.on('exit', onSpawnExit);
}
else {
console.log("New GST pipeline rejected because gstMuxer != undefined.");
}
});
});
httpServer.listen(port);
console.log(`Camera Stream App listening at http://localhost:${port}`)
process.on('uncaughtException', function (err) {
console.log(err);
});
//functions
function onSpawnError(data) {
console.log(data.toString());
}
function onSpawnExit(code) {
if (code != null) {
console.log('GStreamer error, exit code ' + code);
}
}
function getGstPipelineArguments(tcpServer) {
//Replace 'videotestsrc', 'pattern=ball' with camera source in below GStreamer pipeline arguments.
//Note: Every argument should be written in single quotes as done below
var args =
['videotestsrc', 'pattern=ball',
'!', 'video/x-raw,width=320,height=240,framerate=100/1',
'!', 'vpuenc_h264', 'bitrate=2000',
'!', 'mp4mux', 'fragment-duration=10',
'!', 'tcpclientsink', 'host=localhost',
'port=' + tcpServer.address().port];
return args;
}
并分享 HTML 代码:
<!DOCTYPE html>
<head>
<title>GStreamer with NodeJS Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=0.9">
<style>
html,
body {
overflow: hidden;
}
</style>
<script>
function buffer() {
//Start playback as soon as possible to minimize latency at startup
var dStream = document.getElementById('vidStream');
try {
dStream.play();
} catch (error) {
console.log("Error in buffer() method.");
console.log(error);
}
}
</script>
</head>
<body onload="buffer();">
<video id="vidStream" width="640" height="480" muted>
<source src="/stream" type="video/mp4" />
<source src="/stream" type="video/webm" />
<source src="/stream" type="video/ogg" />
<!-- fallback -->
Your browser does not support the <code>video</code> element.
</video>
</body>
这里有一个很好的 gstreamer(和浏览器等其他应用程序)集成测试:https://github.com/sipsorcery/webrtc-echoes/tree/master/gstreamer。它可以工作,但怪癖很少(至少在 chrome 中)。它从此 gstreamer 管道获取数据
pipeline =
gst_parse_launch ("webrtcbin bundle-policy=max-bundle name=sendonly "
"videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay ! "
"queue ! " RTP_CAPS_VP8 " ! sendonly. "
, &error);
并为浏览器打开一个网络服务器来获取这个流。您必须手动打开 index.html
在线有很多示例将 GStreamer 管道与“tcpclientsink”或“udpsink”与 NodeJS 一起使用,以使用 GStreamer 管道输出到 Web 浏览器。
但我找不到任何示例或文档来清楚地解释如何将 webrtcbin 管道与 NodeJS 服务器一起使用以将流发送到 Web 浏览器。
我有以下 GStreamer 管道:
gst-launch-1.0 videotestsrc \
! queue ! vp8enc ! rtpvp8pay \
! application/x-rtp,media=video,encoding-name=VP8,payload=96 \
! webrtcbin name=sendrecv
有人可以帮助使用基于 NodeJS 的服务器使用此管道以在 Web 浏览器上显示流吗?
这是一个类似的例子,但它使用了 tcpclientsink
:
https://tewarid.github.io/2011/04/26/stream-live-webm-video-to-browser-using-node.js-and-gstreamer.html
不幸的是,事情并没有那么简单。您必须有某种方式与浏览器交互才能交换 SDP offer/answer,以及 ICE 候选人交换。
你可以看例子here
更新: 最后,我能够使用问题中提到的 NodeJS 教程实现 GStreamer 到浏览器。这是一个概念验证代码,如果需要(或者在教程 link 从互联网上删除的情况下),有人可以使用它:
var express = require('express')
var http = require('http')
var net = require('net');
var child = require('child_process');
require('log-timestamp'); //adds timestamp in console.log()
var app = express();
app.use(express.static(__dirname + '/'));
var httpServer = http.createServer(app);
const port = 9001; //change port number is required
//send the html page which holds the video tag
app.get('/', function (req, res) {
res.send('index.html');
});
//stop the connection
app.post('/stop', function (req, res) {
console.log('Connection closed using /stop endpoint.');
if (gstMuxer != undefined) {
gstMuxer.kill(); //killing GStreamer Pipeline
console.log(`After gstkill in connection`);
}
gstMuxer = undefined;
res.end();
});
//send the video stream
app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type': 'video/webm',
});
var tcpServer = net.createServer(function (socket) {
socket.on('data', function (data) {
res.write(data);
});
socket.on('close', function (had_error) {
console.log('Socket closed.');
res.end();
});
});
tcpServer.maxConnections = 1;
tcpServer.listen(function () {
console.log("Connection started.");
if (gstMuxer == undefined) {
console.log("inside gstMuxer == undefined");
var cmd = 'gst-launch-1.0';
var args = getGstPipelineArguments(this);
var gstMuxer = child.spawn(cmd, args);
gstMuxer.stderr.on('data', onSpawnError);
gstMuxer.on('exit', onSpawnExit);
}
else {
console.log("New GST pipeline rejected because gstMuxer != undefined.");
}
});
});
httpServer.listen(port);
console.log(`Camera Stream App listening at http://localhost:${port}`)
process.on('uncaughtException', function (err) {
console.log(err);
});
//functions
function onSpawnError(data) {
console.log(data.toString());
}
function onSpawnExit(code) {
if (code != null) {
console.log('GStreamer error, exit code ' + code);
}
}
function getGstPipelineArguments(tcpServer) {
//Replace 'videotestsrc', 'pattern=ball' with camera source in below GStreamer pipeline arguments.
//Note: Every argument should be written in single quotes as done below
var args =
['videotestsrc', 'pattern=ball',
'!', 'video/x-raw,width=320,height=240,framerate=100/1',
'!', 'vpuenc_h264', 'bitrate=2000',
'!', 'mp4mux', 'fragment-duration=10',
'!', 'tcpclientsink', 'host=localhost',
'port=' + tcpServer.address().port];
return args;
}
并分享 HTML 代码:
<!DOCTYPE html>
<head>
<title>GStreamer with NodeJS Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=0.9">
<style>
html,
body {
overflow: hidden;
}
</style>
<script>
function buffer() {
//Start playback as soon as possible to minimize latency at startup
var dStream = document.getElementById('vidStream');
try {
dStream.play();
} catch (error) {
console.log("Error in buffer() method.");
console.log(error);
}
}
</script>
</head>
<body onload="buffer();">
<video id="vidStream" width="640" height="480" muted>
<source src="/stream" type="video/mp4" />
<source src="/stream" type="video/webm" />
<source src="/stream" type="video/ogg" />
<!-- fallback -->
Your browser does not support the <code>video</code> element.
</video>
</body>
这里有一个很好的 gstreamer(和浏览器等其他应用程序)集成测试:https://github.com/sipsorcery/webrtc-echoes/tree/master/gstreamer。它可以工作,但怪癖很少(至少在 chrome 中)。它从此 gstreamer 管道获取数据
pipeline =
gst_parse_launch ("webrtcbin bundle-policy=max-bundle name=sendonly "
"videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay ! "
"queue ! " RTP_CAPS_VP8 " ! sendonly. "
, &error);
并为浏览器打开一个网络服务器来获取这个流。您必须手动打开 index.html