JSmpeg未播放来自WebSocket流的音频

ztmd8pv5  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(458)

我正在尝试使用ffmpeg通过从https://github.com/phoboslab/jsmpeg获取的node js中编写的Web Socket relay将RTSP流传输到web浏览器,在浏览器上我正在使用JSMpeg显示RTSP流,视频播放正常,但音频没有播放,
ffmpeg命令:

ffmpeg -rtsp_transport tcp -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4 
       -f mpegts -c:v mpeg1video -c:a mp2 http://127.0.0.1:8081/stream_from_ffmpeg/<my_secret>

node js Web Socket relay:

// Use the websocket-relay to serve a raw MPEG-TS over WebSockets. You can use
// ffmpeg to feed the relay. ffmpeg -> websocket-relay -> browser
// Example:
// node websocket-relay yoursecret 8081 8082
// ffmpeg -i <some input> -f mpegts http://localhost:8081/yoursecret

var fs = require('fs'),
    http = require('http'),
    WebSocket = require('ws');

if (process.argv.length < 3) {
    console.log(
        'Usage: \n' +
        'node websocket-relay.js <secret> [<stream-port> <websocket-port>]'
    );
    process.exit();
}

var STREAM_SECRET = process.argv[2],
    STREAM_PORT = process.argv[3] || 8081,
    WEBSOCKET_PORT = process.argv[4] || 8082,
    RECORD_STREAM = false;

// Websocket Server
var socketServer = new WebSocket.Server({port: WEBSOCKET_PORT, perMessageDeflate: false});
socketServer.connectionCount = 0;
socketServer.on('connection', function(socket, upgradeReq) {
    socketServer.connectionCount++;
    console.log(
        'New WebSocket Connection: ',
        (upgradeReq || socket.upgradeReq).socket.remoteAddress,
        (upgradeReq || socket.upgradeReq).headers['user-agent'],
        '('+socketServer.connectionCount+' total)'
    );
    socket.on('close', function(code, message){
        socketServer.connectionCount--;
        console.log(
            'Disconnected WebSocket ('+socketServer.connectionCount+' total)'
        );
    });
});
socketServer.broadcast = function(data) {
    socketServer.clients.forEach(function each(client) {
        if (client.readyState === WebSocket.OPEN) {
            client.send(data);
        }
    });
};

// HTTP Server to accept incoming MPEG-TS Stream from ffmpeg
var streamServer = http.createServer( function(request, response) {
    var params = request.url.substr(1).split('/');

    if (params[0] !== STREAM_SECRET) {
        console.log(
            'Failed Stream Connection: '+ request.socket.remoteAddress + ':' +
            request.socket.remotePort + ' - wrong secret.'
        );
        response.end();
    }

    response.connection.setTimeout(0);
    console.log(
        'Stream Connected: ' +
        request.socket.remoteAddress + ':' +
        request.socket.remotePort
    );
    request.on('data', function(data){
        socketServer.broadcast(data);
        if (request.socket.recording) {
            request.socket.recording.write(data);
        }
    });
    request.on('end',function(){
        console.log('close');
        if (request.socket.recording) {
            request.socket.recording.close();
        }
    });

    // Record the stream to a local file?
    if (RECORD_STREAM) {
        var path = 'recordings/' + Date.now() + '.ts';
        request.socket.recording = fs.createWriteStream(path);
    }
})
// Keep the socket open for streaming
streamServer.headersTimeout = 0;
streamServer.listen(STREAM_PORT);

console.log('Listening for incoming MPEG-TS Stream on http://127.0.0.1:'+STREAM_PORT+'/<secret>');
console.log('Awaiting WebSocket connections on ws://127.0.0.1:'+WEBSOCKET_PORT+'/');

前端代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./jsmpeg.min.js"></script>
    <title>Document</title>
  </head>
  <body>
    <canvas id="video-canvas"></canvas>
  </body>
  <script>
    let url;
    let player;
    let canvas = document.getElementById("video-canvas");
    let ipAddr = "127.0.0.1:8082";
    window.onload = async() => {
      url = `ws://${ipAddr}`;
      player = new JSMpeg.Player(url, { canvas: canvas, });
    };

  </script>
</html>

上面的代码工作正常,并播放视频,但没有音频正在播放。
将播放器对象内的音频上下文状态从挂起更改为运行

player.audioOut.context.onstatechange = async () => {
    console.log("Event triggered by audio");

    if (player.audioOut.context === "suspended") {
        await player.audioOut.context.resume();
    }
}
to94eoyn

to94eoyn1#

RTSP-Relay实现了该系统:https://github.com/k-yle/rtsp-relay
这是一个非常好的库,如果您有兴趣自己滚动它,我建议您查看源代码。它加载一个保存ffmpeg二进制文件的节点模块(因此您的系统上不需要ffmpeg),生成它来处理rtsp连接,并将ffmpeg输出通过管道传输到该连接的WebSocket。处理连接和重试非常好。它还有一个客户端版本,提供了一个帮助器来连接WebSocket音频流到客户端。
通过这个库,当音频是mpeg4 aac音频时,我可以播放音频(和视频)。注意-我需要提供一个按钮点击开始音频流。我使用mediamtx / rtsp-simple-server获取一个流并将pcm ulaw音频转换为aac。
它真的下来知道你在不同的阶段使用什么格式。

相关问题