
这些天,虚拟现实正在兴起。 以前是独家保留的设备 疯狂的科学家 有大钱的怪胎 来自国防部 回到“割草机人”时代,目前普通百姓负担得起; 那些口袋空了的人可以根据许多食谱,用纸板和智能手机组装一个VR头戴式耳机。
VR可以带来比3-4-5-6-7-something-D电影院更多的收益。 假设您居住在芝加哥,并且想将诚实赚取的资源投资到房地产上-佛罗里达州沿海的某个地方。 如您所知,最好选择自己居住和当场居住,但是如果您不能花足够的时间去做呢? 这是需要虚拟现实的地方。 试想一下:特工在房间里设置了一个特殊的摄像头,您不用离开自己喜欢的椅子就可以检查这个房间,转过头,甚至可以欣赏带有18世纪壁画的“希腊诸神开派对!”的天花板。
然后,仍然没有离开这个地方,您可能想知道您的孩子在幼儿园做什么。 再说一次:相机在游戏室中,通过检查孩子所处的所有角落,您可以获得身临其境的感官体验 隐藏 。
现在,我们将弄清楚如何确保一切正常,并且 房地产经纪人 孩子们不要分散。
VR图片的细微差别
从技术上讲,VR媒体流与普通媒体没有区别。 它是视频轨道和音频轨道。 但是有细微差别。
VR流假定为立体声图像。 一台特殊的相机用两个视角观察世界 眼睛 镜头像机器人一样张开(180度)。

图片合并在一帧中

因此,应在观看者的设备上安装特殊的播放器,以制作两张图片。 如您所见,帧的纵横比为2:1,从而为每只眼睛制作了FullHD图片。
VR广播的细微差别
因此,我们正在谈论以高比特率广播4K流。 我们有什么? 我们有RTMP和WebRTC。
RTMP是 便宜的 可靠实用。 它使用TCP,在通道不太理想的情况下很有用。 为发布客户提供了各种软件解决方案,包括付费和免费的。 但是,尽管有很多优点,RTMP仍具有较高的延迟。 在之前的一篇文章中,我们注意到720p流中的延迟为2-3秒。 在某些情况下,延迟是可以接受的,但是VR会落后于现实,孩子们肯定会分散。
WebRTC真的很棒。 有了良好的渠道,延迟的测量单位是毫秒,而现实将依然存在。 但是有细微差别。
首先,默认情况下,WebRTC在UDP上运行,这将导致信道质量下降至少一点的损失。 对于4K数据流,通道上的任何小东西都已经恶化。 这可以通过切换到TCP传输来解决,但是在这种情况下...
其次,WebRTC是通过浏览器广播的,我们都知道哪种浏览器当前是全球最受欢迎的(破坏者-不是IE6)。 在此流行的浏览器中,引擎级别的最大发布比特率是2500 kbps。 正如谷歌认为 ,对于FullHD而言已足够,但对于4K而言则不足。 如果比特率未加快到5-10 Mbps,则观看者将看到移动的水彩斑点,而不是虚拟现实。 幸运的是,有一些特殊设置可以超频工作的比特率 差不多 Chromium引擎上的所有浏览器。 然后,克服这一障碍,我们将遇到...
第三,我们将遇到信道带宽。 要发布和播放具有上述比特率的VR图片,客户端需要使用20+ Mbit或更好的50,甚至更好的100+ Mbit的频道进行下载和上传。 在这种情况下,这些不应是提供商在广告手册中谈论的参数,而应是从客户端到服务器的实际带宽。 顺便说一下,阅读如何在不使用iperf和命令行的情况下进行测量 。 相应地,在服务器端,如果设想到大量流,则希望具有10 Gb。
第四是对渠道的要求。 对4K流进行转码将占用服务器上过多的处理器资源。 因此,您必须选择昂贵的特大服务器,或者在昂贵的视频卡上使用编码,或者避免转码。 也就是说,在广播过程中,请勿更改流的分辨率,帧速率和比特率。
让我们尝试这样做
让我们来:
将相机安装在桌子或三脚架上

与外部驱动器一样,通过具有1A电源的USB 3.0将其连接到PC

请注意,相机对设备非常敏感,如果笔记本电脑具有2个USB 3.0端口,则可能会拒绝使用其中之一。 确保不要使用廉价的中文连接电缆; 标准提供的所有引脚都应安装到位。 即使连接完美,相机也会产生毛刺,就像雷雨中的旧电视一样。 唯一积极的一点是Windows 10不需要驱动程序。 这是一个诚实的即插即用型连接。
我们将在服务器端设置必要的比特率限制
webrtc_cc_min_bitrate=5000000 webrtc_cc_max_bitrate=10000000
在Chrome中,打开示例页面 ,允许设置必要的参数以捕获来自相机的流,然后进行设置
- 分辨率3072x1536
- FPS 24(从浏览器广播时,相机仅支持此FPS)
- TCP传输
并配置SDP设置,以使浏览器不会降低客户端的比特率
x-google-max-bitrate=10000;x-google-min-bitrate=5000
或服务器端(在这种情况下,设置将对所有发布客户端均有效)
webrtc_sdp_min_bitrate_bps=5000000 webrtc_sdp_max_bitrate_bps=10000000

让我们发布相机中的视频流

现在,让我们尝试使用普通的WebRTC播放器播放流

一切都很好。 虚拟性不是真正的虚拟性。 现在,让我们在页面上嵌入的特殊播放器中播放相同的流

现在好了(我们也养猫了)。 如果您在移动设备或VR眼镜上播放视频流,则可以转头,我们将在PC的浏览器中移动鼠标。 这个房间里某个地方藏着一个孩子。 让我们向左看

现在在右边

现在起来

孩子在哪 他在那里,躲在窗帘后面。 但是猫看见了他!
我们需要更多代码!
客户端的代码很少。
让我们从浏览器页面发布流
session.createStream({ name: streamName, display: localVideo, cacheLocalResources: true, transport: "TCP", sdpHook: rewriteSdp, constraints: { audio:true, video: { width: 3072, height: 1536, frameRate: 24 } } }).publish();
SDP浏览器覆盖功能
function rewriteSdp(sdp) { var sdpStringFind = "a=fmtp:(.*) (.*)"; var sdpStringReplace = "a=fmtp:$1 $2;x-google-max-bitrate=10000;x-google-min-bitrate=5000"; var newSDP = sdp.sdpString.toString(); newSDP = newSDP.replace(new RegExp(sdpStringFind,"g"), sdpStringReplace); return newSDP; }
一个带有VR播放器的页面示例
<!DOCTYPE html> <html> <head> <title>WebRTC Delight</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="../../../../flashphoner.js"></script> <script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script> <script type="text/javascript" src="../../dependencies/js/utils.js"></script> <script src="dl8-player.js" async></script> <meta name="dl8-custom-format" content='{"name": "STEREO_TERPON","base":"STEREO_MESH","params":{"uri": "03198702.json"}}'> </head> <body> <div style="width: 50%;" id="display"> <dl8-live-video id="remoteVideo" format="STEREO_TERPON"> \<source> </dl8-live-video> </div> <input class="form-control" type="text" id="playStream" placeholder="Stream Name"> <button id="playBtn" type="button" class="btn btn-default" disabled>Play</button> <button id="stopBtn" type="button" class="btn btn-default" disabled>Stop</button> <script> Flashphoner.init({flashMediaProviderSwfLocation: '../../../../media-provider.swf'}); var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS; var STREAM_STATUS_INFO = Flashphoner.constants.STREAM_STATUS_INFO; var playBtn = document.getElementById('playBtn'); var display = document.getElementById('display'); var dl8video = null; var url = setURL(); document.addEventListener('x-dl8-evt-ready', function () { dl8video = document.getElementById('remoteVideo'); $('#playBtn').prop('disabled', false).click(function() { playStream(); }); }); function playStream() { $('#playBtn').prop('disabled', true); $('#stopBtn').prop('disabled', false); var video = dl8video.contentElement; Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) { var session = Flashphoner.getSessions()[0]; session.createStream({ name: document.getElementById('playStream').value, display: display, remoteVideo: video, transport: "TCP" }).on(STREAM_STATUS.PLAYING, function (stream) { dl8video.start(); $('#stopBtn').prop('disabled', false).click(function() { $('#playBtn').prop('disabled', false); $('#stopBtn').prop('disabled', true); stream.stop(); dl8video.exit(); }); }).play(); }) } </script> </body> </html>
通常,在为播放器创建流时(查询session.createStream()
),我们传递div元素,视频元素将安装到div元素中,以通过WebRTC播放流。 但是VR播放器使用自己的视频元素,我们需要以某种方式将其转发到所用API的代码中。 为此,我们将带有remoteVideo
参数的第三方播放器的video元素直接传递给session.createStream()
demo.flashphoner.com用作服务器端; 以下链接提供了Web应用程序示例。
在您的VR事业中祝您好运! 直播愉快!
友情链接
- 服务器WebRTC over TCP的通道质量指示器 -客户端到服务器通道的质量控制
- 来自浏览器或移动设备的网络摄像机的视频广播 -来自浏览器的WebRTC流
- WCS与VR播放器一起使用的文档
- WCS-用于通过WebRTC传输VR 360视频的服务器