我目前正在寻找一种存储传入的webrtc视频流的最佳方式。我正在使用webrtc(通过chrome)加入视频聊天,我想将每个参与的视频流记录到每个参与者的浏览器中。 我正在研究的解决方案是:
拦截进入浏览器的网络数据包,例如使用Whireshark然后解码。撰写本文后:https://webrtchacks.com/video_replay/
修改浏览器以将记录存储为文件,例如通过修改Chromium本身
任何屏幕录像机或使用xvfb& amp;由于资源限制,ffmpeg不是一个选项。有没有其他方法可以让我捕获数据包或编码视频作为文件?解决方案必须在Linux上运行。
答案 0 :(得分:0)
捕获数据包只会为您提供网络数据包,然后您需要将这些数据包转换为帧并放入容器中。 Janus等服务器可以录制视频。
运行无头镀铬并使用javascript MediaRecorder API是另一种选择,但资源更加沉重。
答案 1 :(得分:0)
如果媒体流是您想要的,则方法是覆盖浏览器的PeerConnection。这是一个例子:
在扩展程序清单中添加以下内容脚本:
content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["payload/inject.js"],
"all_frames": true,
"match_about_blank": true,
"run_at": "document_start"
}
]
inject.js
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);
我在谷歌视频聊天中通过语音通话对此进行了测试,看到通过pc.addStream添加了两个mediaStream,并通过pc.ontrack添加了一个音轨。 addStream似乎是本地媒体流,ontrack中的事件对象是一个RTCTrackEvent,它有一个stream对象。我认为这就是你要找的东西。
要从extenion的内容脚本访问这些流,您需要创建音频元素并设置" srcObject"媒体流的属性:例如
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);
}
然后在您的内容脚本中,您可以监听该事件/访问媒体流,如下所示:
window.addEventListener("remoteStreamAdded", function(e) {
elm = document.getElementById("remoteStream");
var stream = elm.captureStream();
})
使用您的内容脚本可以使用捕获流,您可以使用它完成任何您想要的任何操作。例如,MediaRecorder非常适合记录流,或者您可以使用像peer.js或者binary.js这样的内容来流式传输到另一个源。
我还没有对此进行测试,但也应该可以覆盖本地流。例如,在inject.js中,您可以建立一些空白媒体流,覆盖navigator.mediaDevices.getUserMedia,而不是返回本地媒体流返回您自己的媒体流。
这个方法应该可以在firefox和其他人中使用,假设您使用extenion / app在文档的开头加载inject.js脚本。在任何目标库之前加载它是使这项工作成为关键。
已编辑以获取更多详细信息
已编辑以获取更多详细信息