点此查看原文
本文使用了过时的 Flash技术来实现,请尽量关注并使用最新的 HTML5 DASH + WebRTC技术来实现具体应用。
首先在一台 Linux 服务器上下载 AMS ,点此下载。
➜ AMS ./installAMSDo you agree with the license agreement? (y/n): y Please enter your Adobe Media Server 5 serial number: #不推荐使用盗版,当然搜一下就能搜到 2333# 之后一路回车就好,如果不需要 HTTP Fallback 的话可以把 80 端口去掉 service ams start
安装并启动之后,如果端口监听正常,就不需要什么配置
然后打开 tools/multicast/configurator/configurator.html
Multicast 类型选择 Peer to Peer ,服务器输入 rtmfp://SERVER_IP/multicast ,password 随便输入一个,点击生成然后选择 Show GroupSpecs
Groupspec With Auth 就是直播用的,Groupspec Without Auth 是观看用的,两个都记下来。
接下来,使用直播大师进行推流,直播大师配置界面如下:
然后,在【直播大师】的主控面板中点击“开始编码”按钮。
其实,编码开始后就可以观看了,但是由于播放器并没有加入 P2P Netgroup , 还需要对播放器动手脚,我们拿 Video.JS 的 SWF 版开刀,先下载源代码
git clone https://github.com/videojs/video-js-swfnpm install
用文本编辑器打开,定位到 src/com/videojs/providers/RTMPVideoProvider.as 修改几处内容
// 第 26 行加入private var _ng:NetGroup;private var groupSpec:String = "你的 GropSpecWithoutAuth";// 422 行左右private function initNetStream():void{ if(_ns != null){ _ns.removeEventListener(NetStatusEvent.NET_STATUS, onNetStreamStatus); _ns = null; } _ns = new NetStream(_nc,groupSpec); _ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStreamStatus); _ns.client = this; _ns.bufferTime = 1; _ns.play(_src.streamURL); _videoReference.attachNetStream(_ns); _model.broadcastEventExternally(ExternalEventName.ON_LOAD_START); _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_STREAM_READY, {ns:_ns})); }// 469 行 左右private function onNetConnectionStatus(e:NetStatusEvent):void{ switch(e.info.code){ case "NetConnection.Connect.Success": // 连接成功 _model.broadcastEventExternally(ExternalEventName.ON_RTMP_CONNECT_SUCCESS); if(_src.connectionURL.indexOf("rtmfp") == 0){ // 如果是 RTMFP 链接 _ng = new NetGroup(_nc,groupSpec); // 创建 NetGroup _ng.addEventListener(NetStatusEvent.NET_STATUS,onNetConnectionStatus); _model.broadcastEventExternally("P2P.waitforconf"); // 等待用户选择允许或拒绝 // 不知道那几个国产流氓视频网站是怎么跳过这个是否开启 P2P 的提示 }else{ _ns = new NetStream(_nc); _ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStreamStatus); _ns.client = this; _ns.bufferTime = 1; _ns.play(_src.streamURL); _videoReference.attachNetStream(_ns); _model.broadcastEventExternally(ExternalEventName.ON_LOAD_START); _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_STREAM_READY, {ns:_ns})); } break; case "NetConnection.Connect.Failed": if(_ncRTMPCurrentRetry < _ncRTMPRetryThreshold){ _ncRTMPCurrentRetry++; _model.broadcastErrorEventExternally(ExternalErrorEventName.RTMP_CONNECT_FAILURE); _rtmpRetryTimer.start(); _model.broadcastEventExternally(ExternalEventName.ON_RTMP_RETRY); } break; case "NetGroup.Connect.Success": // 用户选择了允许 P2P ,开始播放 initNetStream(); break; case "NetGroup.Connect.Rejected": // 用户选择了拒绝 P2P ,重新连接,不带 netgroup _ns = new NetStream(_nc); _ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStreamStatus); _ns.client = this; _ns.bufferTime = 1; _ns.play(_src.streamURL); _videoReference.attachNetStream(_ns); _model.broadcastEventExternally(ExternalEventName.ON_LOAD_START); _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_STREAM_READY, {ns:_ns})); break; default: if(e.info.level == "error"){ _model.broadcastErrorEventExternally(e.info.code); _model.broadcastErrorEventExternally(e.info.description); } break; } _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_NETCONNECTION_STATUS, {info:e.info})); }// 608 行左右,default 之前加入case "NetStream.Video.DimensionChange": // P2P 的视频会比音频后到一会,收到此事件代表真正开始播放 _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_VIDEO_DIMENSION_UPDATE, {videoWidth: _videoReference.videoWidth, videoHeight: _videoReference.videoHeight})); if(_model.metadata && _videoReference) // 修正视频分辨率,使其充满屏幕 { _model.metadata.width = _videoReference.videoWidth; _model.metadata.height = _videoReference.videoHeight; } _model.broadcastEventExternally("videoplaying"); // 给 JS 广播一个视频已开始播放的信号 break;
至此代码修改完成,编译
grunt dist
运行之后即可在 dist 得到新的 swf 文件,替换掉 vjs 自带的 swf ,然后通过以下 JS 代码加载视频流
SWFElement.vjs_setProperty("rtmpConnection","rtmfp://SERVER_IP/multicast"); SWFElement.vjs_setProperty("rtmpStream","流名称");
打开两台电脑测试,就可以看到彼此的上行流量,说明P2P直播已经正常工作。当然,如果有更多的客户端加入,P2P的加速效果就会更加明显,这正是P2P的技术优势所在。