捕获传入的WebRTC视频流的方法(客户端)

问题描述 投票:0回答:2

我目前正在寻找一种存储传入的webrtc视频流的最佳方法。我正在使用webrtc(通过chrome)加入视频聊天,我想将每个参与的视频流记录到每个参与者的浏览器中。我正在研究的解决方案是:

  • 拦截进入浏览器的网络数据包,例如使用Wireshark然后解码。以下文章:qazxsw poi
  • 修改浏览器以将记录存储为文件,例如通过修改Chromium本身

由于资源限制,任何屏幕录像机或使用xvfb和ffmpeg等解决方案都不是选项。有没有其他方法可以让我捕获数据包或编码视频作为文件?解决方案必须在Linux上运行。

google-chrome webrtc chromium openwebrtc
2个回答
0
投票

捕获数据包只会为您提供网络数据包,然后您需要将这些数据包转换为帧并放入容器中。像https://webrtchacks.com/video_replay/这样的服务器可以录制视频。

运行无头chrome并使用javascript MediaRecorder API是另一种选择,但对资源更加沉重。


0
投票

如果媒体流是你想要的方法是覆盖浏览器的PeerConnection。这是一个例子:

在扩展清单中添加以下内容脚本:

Janus

inject.js

content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["payload/inject.js"],
      "all_frames": true,
      "match_about_blank": true,
      "run_at": "document_start"
    }
]

我在谷歌视频聊天中通过语音通话对此进行了测试,看到通过pc.addStream添加了两个mediaStream,并通过pc.ontrack添加了一个音轨。 addStream似乎是本地媒体流,var inject = '('+function() { //overide the browser's default RTCPeerConnection. var origPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection; //make sure it is supported if (origPeerConnection) { //our own RTCPeerConnection var newPeerConnection = function(config, constraints) { console.log('PeerConnection created with config', config); //proxy the orginal peer connection var pc = new origPeerConnection(config, constraints); //store the old addStream var oldAddStream = pc.addStream; //addStream is called when a local stream is added. //arguments[0] is a local media stream pc.addStream = function() { console.log("our add stream called!") //our mediaStream object console.dir(arguments[0]) return oldAddStream.apply(this, arguments); } //ontrack is called when a remote track is added. //the media stream(s) are located in event.streams pc.ontrack = function(event) { console.log("ontrack got a track") console.dir(event); } window.ourPC = pc; return pc; }; ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection'].forEach(function(obj) { // Override objects if they exist in the window object if (window.hasOwnProperty(obj)) { window[obj] = newPeerConnection; // Copy the static methods Object.keys(origPeerConnection).forEach(function(x){ window[obj][x] = origPeerConnection[x]; }) window[obj].prototype = origPeerConnection.prototype; } }); } }+')();'; var script = document.createElement('script'); script.textContent = inject; (document.head||document.documentElement).appendChild(script); script.parentNode.removeChild(script); 中的事件对象是一个RTCTrackEvent,它有一个stream对象。我认为这就是你要找的东西。

要从extenion的内容脚本访问这些流,您需要创建音频元素并将“srcObject”属性设置为媒体流:例如

ontrack

然后在您的内容脚本中,您可以监听该事件/访问媒体流,如下所示:

pc.ontrack = function(event) {

    //check if our element exists
    var elm = document.getElementById("remoteStream");
    if(elm == null) {
        //create an audio element
        elm = document.createElement("audio");
        elm.id = "remoteStream";

    }

    //set the srcObject to our stream. not sure if you need to clone it
    elm.srcObject = event.streams[0].clone();
    //write the elment to the body
    document.body.appendChild(elm);

    //fire a custom event so our content script knows the stream is available.
    // you could pass the id in the "detail" object. for example:
    //CustomEvent("remoteStreamAdded", {"detail":{"id":"audio_element_id"}})
    //then access if via e.detail.id in your event listener.
    var e = CustomEvent("remoteStreamAdded");
    window.dispatchEvent(e);

}

利用您的内容脚本可用的捕获流,您可以使用它完成任何您想要的任何操作。例如,MediaRecorder非常适合记录流,或者您可以使用像peer.js或者binary.js这样的内容来流式传输到另一个源。

我没有测试过这个,但也应该可以覆盖本地流。例如,在inject.js中,您可以建立一些空白媒体流,覆盖navigator.mediaDevices.getUserMedia,而不是返回本地媒体流返回您自己的媒体流。

假设您使用extenion / app在文档的开头加载inject.js脚本,此方法应该在firefox和其他人中工作。它在任何目标库之前加载是使这项工作成为关键的关键。

编辑了更多细节

编辑更详细

© www.soinside.com 2019 - 2024. All rights reserved.