3

当我在 Chrome 中使用 WebRTC 时,我注意到这些流的持久性仍然有些不稳定。我需要在显示它的元素显示之前创建一个视频流(从技术上讲,我最初只需要音轨,但是没有 replaceTrack() 的重新协商似乎本身就是一个问题,所以我现在同时启用两者)。

然后该元素由 JavaScript 动态呈现,并需要开始接收 WebRTC 视频。问题是,在创建 WebRTC 时,我想要展示的这个视频元素还不存在。我没有办法告诉 WebRTC 在流开始后更改正在渲染的视频元素,这可能吗?我主要是在玩 SimpleWebRTC,但我对直接使用 WebRTC 持开放态度——通过查看文档,我也找不到使用原始 WebRTC 的方法。我还尝试将原始视频元素移动到新元素中,但这会导致视频流中断/停止:

newElement.appendChild(originalWebRTCVideoTag);

没有杀死整个流并重新启动,我有什么选择?

更新

对于这两种方法,videoTag 是一个通用的 DOM 视频标签,webrtc 是一个WebRTC对象实例,具有通过 SimpleWebRTC(simpleWebRtc.webrtc,SimpleWebRTC 包装)建立的工作连接。我现在正在为那些想要查看实际代码的人整理一个 JSFiddle,但这应该足以重现这一点。

// this doesn't seem to be working in stackoverflow, probably because it rejects video camera capture

var simplertc = new SimpleWebRTC({
  localVideoEl: 'webrtc-local',
  remoteVideosEl: 'webrtc-remote',
  media: {"audio": true, "video": {
    "optional": [{"minWidth": "640"}, {"minHeight": "480"}], "mandatory": {}
  }},
  autoRequestMedia: true
});
var webrtc = simplertc.webrtc;

// this portion is overly simplified, in this case there is no point
// in creating this dynamically, in the app I'm working on this element 
// is generated much later
$('#dynamic').appendTo('<video id="dynamic-video"></video>');
var videoTag = $('#dynamic-video')[0];

simplertc.on('readyToCall', function() {
  simplertc.joinRoom('my-room-875385864'); // random name
  
  // by this time the local video should be ready, we don't need remote ones for our test
  // test case 1 (replace with logic from test case 2 if needed)
  videoTag.srcObject = webrtc.localStreams[0];
  // end test case
});
video {
  border: 1px solid red;
  width: 200px;
}

/* overlap with original video is intentional to show hardware acceleration effect */
#dynamic {
  position: absolute;
  border: 1px solid black;
  width: 200px;
  height: 200px;
  left: 100px;
  top:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://simplewebrtc.com/latest-v2.js"></script>
<div id='webrtc'>
  <video id='webrtc-local'></video>
  <div id='webrtc-remote'></div>
</div>
<div id='dynamic'>
</div>

方法 1,在尝试方法 2 时偶然发现了这一点

尝试了以下方法,它可以工作,但比我想要的慢得多,大约 5 FPS:

// note that I can just as easily use remote streams here
videoTag.srcObject = webrtc.localStreams[0]

具有讽刺意味的是,虽然更多地混淆了这种方法,但我不小心重叠了 webRTC 元素的视频区域和生成的(videoTag),即使 webRTC 在背景上,它重叠的 videoTag 的那个角落确实是实时运行的,不像其余元素继续以 3-5 FPS 运行。这让我相信这里的问题是硬件加速。我可以以某种方式为 videoTag 启用它吗?

方法二

var media = new MediaSource();
videoTag.src = URL.createObjectURL(media);
// guessing mimetype from a few WebRTC tutorials I stumbled upon
var srcBuf = media.addSourceBuffer(‘video/webm;codecs=”vp8, vorbis”’);

// need to convert webrtc.localStreams[0] or its video track to a buffer somehow???
srcBuf.appendBuffer(/* buffer */);

进一步的研究

这可能是 Chrome 中的一个错误,一个看似有效的黑客解决方法是确保新生成的视频元素与原始视频元素完全重叠(即使原始视频元素设置为在所有其他元素后面的背景上呈现) (并且在不透明的背景后面)。这似乎启动了硬件加速。

4

1 回答 1

1

您可以使用MediaSource,sourceopen事件, .addSourceBuffer(), .appendBuffer(). 请参阅HTML5 音频流:精确测量延迟?,无法通过 websocket 将视频流式传输到 Firefox

于 2017-02-11T20:36:57.640 回答