首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在web浏览器中使用GStreamer的webrtcbin?

如何在web浏览器中使用GStreamer的webrtcbin?
EN

Stack Overflow用户
提问于 2020-09-17 21:44:00
回答 3查看 11.8K关注 0票数 6

有许多在线使用带有“tcpclient接收器”的GStreamer管道或与NodeJS一起使用"udpsink“的GStreamer管道输出到Web浏览器的示例。

但是,我没有找到任何示例或文档,它们清楚地解释了如何使用带NodeJS服务器的webrtcbin管道将流发送到web浏览器。

我有以下GStreamer管道:

代码语言:javascript
运行
复制
gst-launch-1.0 videotestsrc  \
! queue ! vp8enc ! rtpvp8pay \
! application/x-rtp,media=video,encoding-name=VP8,payload=96 \
! webrtcbin name=sendrecv

有人能帮助使用基于NodeJS的服务器来将流显示到web浏览器上吗?

下面是一个类似的示例,但它使用了tcpclientsinkhttps://tewarid.github.io/2011/04/26/stream-live-webm-video-to-browser-using-node.js-and-gstreamer.html

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-06-08 13:20:54

更新:最后,我用问题中提到的NodeJS管实现了GStreamer到浏览器。这里有一个概念代码的证明,如果需要的话(或者在教程链接从internet上被删除的情况下):

代码语言:javascript
运行
复制
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代码:

代码语言:javascript
运行
复制
<!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>
票数 7
EN

Stack Overflow用户

发布于 2020-09-18 05:39:31

不幸的是,事情并没有那么简单。您必须有某种方式与浏览器进行交互,以便能够交换SDP报价/答案,以及ICE候选人交换。

您可以查看示例这里

票数 3
EN

Stack Overflow用户

发布于 2021-07-20 14:07:22

对于gstreamer (以及其他作为浏览器的应用程序),有一个很好的集成测试可以在这里获得:https://github.com/sipsorcery/webrtc-echoes/tree/master/gstreamer。它工作,与最小的怪癖(至少在铬)。它从这个gstreamer管道中获取数据。

代码语言:javascript
运行
复制
  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);

并为浏览器打开web服务器以获取此流。您必须手动打开index.html

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63946535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档