正在显示
6 个修改的文件
包含
294 行增加
和
11 行删除
| @@ -22,15 +22,15 @@ vhost __defaultVhost__ { | @@ -22,15 +22,15 @@ vhost __defaultVhost__ { | ||
| 22 | enabled on; | 22 | enabled on; |
| 23 | gop_cache on; | 23 | gop_cache on; |
| 24 | queue_length 30; | 24 | queue_length 30; |
| 25 | - #forward 127.0.0.1:19350; | 25 | + forward 127.0.0.1:19350; |
| 26 | hls { | 26 | hls { |
| 27 | - enabled off; | 27 | + enabled on; |
| 28 | hls_path ./objs/nginx/html; | 28 | hls_path ./objs/nginx/html; |
| 29 | hls_fragment 5; | 29 | hls_fragment 5; |
| 30 | hls_window 30; | 30 | hls_window 30; |
| 31 | } | 31 | } |
| 32 | http_hooks { | 32 | http_hooks { |
| 33 | - enabled off; | 33 | + enabled on; |
| 34 | on_connect http://127.0.0.1:8085/api/v1/clients; | 34 | on_connect http://127.0.0.1:8085/api/v1/clients; |
| 35 | on_close http://127.0.0.1:8085/api/v1/clients; | 35 | on_close http://127.0.0.1:8085/api/v1/clients; |
| 36 | on_publish http://127.0.0.1:8085/api/v1/streams; | 36 | on_publish http://127.0.0.1:8085/api/v1/streams; |
| @@ -39,7 +39,7 @@ vhost __defaultVhost__ { | @@ -39,7 +39,7 @@ vhost __defaultVhost__ { | ||
| 39 | on_stop http://127.0.0.1:8085/api/v1/sessions; | 39 | on_stop http://127.0.0.1:8085/api/v1/sessions; |
| 40 | } | 40 | } |
| 41 | transcode { | 41 | transcode { |
| 42 | - enabled off; | 42 | + enabled on; |
| 43 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; | 43 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; |
| 44 | engine ld { | 44 | engine ld { |
| 45 | enabled on; | 45 | enabled on; |
| @@ -94,9 +94,9 @@ vhost dev { | @@ -94,9 +94,9 @@ vhost dev { | ||
| 94 | enabled on; | 94 | enabled on; |
| 95 | gop_cache on; | 95 | gop_cache on; |
| 96 | queue_length 10; | 96 | queue_length 10; |
| 97 | - forward 127.0.0.1:19350; | 97 | + #forward 127.0.0.1:19350; |
| 98 | hls { | 98 | hls { |
| 99 | - enabled on; | 99 | + enabled off; |
| 100 | hls_path ./objs/nginx/html; | 100 | hls_path ./objs/nginx/html; |
| 101 | hls_fragment 5; | 101 | hls_fragment 5; |
| 102 | hls_window 30; | 102 | hls_window 30; |
| @@ -16,7 +16,12 @@ | @@ -16,7 +16,12 @@ | ||
| 16 | <script type='text/javascript'>jwplayer.key = 'N8zhkmYvvRwOhz4aTGkySoEri4x+9pQwR7GHIQ=='; </script> | 16 | <script type='text/javascript'>jwplayer.key = 'N8zhkmYvvRwOhz4aTGkySoEri4x+9pQwR7GHIQ=='; </script> |
| 17 | <script type="text/javascript"> | 17 | <script type="text/javascript"> |
| 18 | function jwplayer_play(url) { | 18 | function jwplayer_play(url) { |
| 19 | - $("#main_modal").show(function(){ | 19 | + var _player = null; |
| 20 | + $("#main_modal").on("hide", function(){ | ||
| 21 | + $("#div_container").remove(); | ||
| 22 | + _player.stop(); | ||
| 23 | + }); | ||
| 24 | + $("#main_modal").on("show", function(){ | ||
| 20 | $("#div_container").remove(); | 25 | $("#div_container").remove(); |
| 21 | 26 | ||
| 22 | var obj = $("<div/>"); | 27 | var obj = $("<div/>"); |
| @@ -35,7 +40,7 @@ | @@ -35,7 +40,7 @@ | ||
| 35 | autostart: true, | 40 | autostart: true, |
| 36 | analytics: { enabled: false} | 41 | analytics: { enabled: false} |
| 37 | }; | 42 | }; |
| 38 | - jwplayer('player_id').setup(conf); | 43 | + _player = jwplayer('player_id').setup(conf); |
| 39 | }); | 44 | }); |
| 40 | $("#main_modal").modal({show:true, keyboard:false}); | 45 | $("#main_modal").modal({show:true, keyboard:false}); |
| 41 | } | 46 | } |
| @@ -21,7 +21,10 @@ | @@ -21,7 +21,10 @@ | ||
| 21 | srs_init($("#txt_url")); | 21 | srs_init($("#txt_url")); |
| 22 | 22 | ||
| 23 | $("#btn_play").click(function(){ | 23 | $("#btn_play").click(function(){ |
| 24 | - $("#main_modal").show(function(){ | 24 | + $("#main_modal").on("hide", function(){ |
| 25 | + $("#div_container").remove(); | ||
| 26 | + }); | ||
| 27 | + $("#main_modal").on("show", function(){ | ||
| 25 | $("#div_container").remove(); | 28 | $("#div_container").remove(); |
| 26 | 29 | ||
| 27 | var obj = $("<div/>"); | 30 | var obj = $("<div/>"); |
| @@ -15,8 +15,123 @@ | @@ -15,8 +15,123 @@ | ||
| 15 | </style> | 15 | </style> |
| 16 | <script type="text/javascript"> | 16 | <script type="text/javascript"> |
| 17 | $(function(){ | 17 | $(function(){ |
| 18 | - srs_init(null); | 18 | + // get the vhost and port to set the default url. |
| 19 | + // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo | ||
| 20 | + // url set to: rtmp://demo:1935/live/livestream | ||
| 21 | + srs_init($("#txt_url")); | ||
| 22 | + | ||
| 23 | + var srs_player = null; | ||
| 24 | + $("#main_modal").on("show", function(){ | ||
| 25 | + $("#div_container").remove(); | ||
| 26 | + | ||
| 27 | + var obj = $("<div/>"); | ||
| 28 | + $(obj).attr("id", "div_container"); | ||
| 29 | + | ||
| 30 | + var player = $("<div/>"); | ||
| 31 | + $(obj).append(player); | ||
| 32 | + $(obj).attr("id", "player_id"); | ||
| 33 | + | ||
| 34 | + $("#player").append(obj); | ||
| 35 | + | ||
| 36 | + var url = $("#txt_url").val(); | ||
| 37 | + | ||
| 38 | + srs_player = new SrsPlayer("player_id", url, 530, 300); | ||
| 39 | + srs_player.on_player_ready = function() { | ||
| 40 | + // hack the callback function, start to play the url. | ||
| 41 | + return srs_player.play(); | ||
| 42 | + } | ||
| 43 | + srs_player.start(); | ||
| 44 | + }); | ||
| 45 | + $("#main_modal").on("hide", function(){ | ||
| 46 | + srs_player.stop(); | ||
| 47 | + }); | ||
| 48 | + | ||
| 49 | + $("#btn_play").click(on_btn_play); | ||
| 50 | + $("#btn_pause").click(function(){ | ||
| 51 | + var _v = $("#btn_pause").text(); | ||
| 52 | + if (_v == "暂停") { | ||
| 53 | + $("#btn_pause").text("继续"); | ||
| 54 | + srs_player.pause(); | ||
| 55 | + } else { | ||
| 56 | + $("#btn_pause").text("暂停"); | ||
| 57 | + srs_player.resume(); | ||
| 58 | + } | ||
| 19 | }); | 59 | }); |
| 60 | + }); | ||
| 61 | + function on_btn_play(){ | ||
| 62 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + function SrsPlayer(container, stream_url, width, height) { | ||
| 66 | + if (!SrsPlayer.__id) { | ||
| 67 | + SrsPlayer.__id = 100; | ||
| 68 | + } | ||
| 69 | + if (!SrsPlayer.__players) { | ||
| 70 | + SrsPlayer.__players = []; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + SrsPlayer.__players.push(this); | ||
| 74 | + | ||
| 75 | + this.container = container; | ||
| 76 | + this.stream_url = stream_url; | ||
| 77 | + this.width = width; | ||
| 78 | + this.height = height; | ||
| 79 | + this.id = SrsPlayer.__id++; | ||
| 80 | + this.callbackObj = null; | ||
| 81 | + } | ||
| 82 | + SrsPlayer.prototype.start = function() { | ||
| 83 | + // embed the flash. | ||
| 84 | + var flashvars = {}; | ||
| 85 | + flashvars.id = this.id; | ||
| 86 | + flashvars.on_player_ready = "__srs_on_player_ready"; | ||
| 87 | + | ||
| 88 | + var params = {}; | ||
| 89 | + params.allowFullScreen = true; | ||
| 90 | + | ||
| 91 | + var attributes = {}; | ||
| 92 | + | ||
| 93 | + var self = this; | ||
| 94 | + | ||
| 95 | + swfobject.embedSWF( | ||
| 96 | + "srs_player/release/srs_player.swf", this.container, | ||
| 97 | + this.width, this.height, | ||
| 98 | + "11.1", "js/AdobeFlashPlayerInstall.swf", | ||
| 99 | + flashvars, params, attributes, | ||
| 100 | + function(callbackObj){ | ||
| 101 | + self.callbackObj = callbackObj; | ||
| 102 | + } | ||
| 103 | + ); | ||
| 104 | + | ||
| 105 | + return this; | ||
| 106 | + } | ||
| 107 | + SrsPlayer.prototype.play = function() { | ||
| 108 | + return this.callbackObj.ref.__play(this.stream_url, this.width, this.height); | ||
| 109 | + } | ||
| 110 | + SrsPlayer.prototype.stop = function() { | ||
| 111 | + return this.callbackObj.ref.__stop(); | ||
| 112 | + } | ||
| 113 | + SrsPlayer.prototype.pause = function() { | ||
| 114 | + return this.callbackObj.ref.__pause(); | ||
| 115 | + } | ||
| 116 | + SrsPlayer.prototype.resume = function() { | ||
| 117 | + return this.callbackObj.ref.__resume(); | ||
| 118 | + } | ||
| 119 | + SrsPlayer.prototype.on_player_ready = function() { | ||
| 120 | + return this.play(); | ||
| 121 | + } | ||
| 122 | + function __srs_on_player_ready(id) { | ||
| 123 | + for (var i = 0; i < SrsPlayer.__players.length; i++) { | ||
| 124 | + var player = SrsPlayer.__players[i]; | ||
| 125 | + | ||
| 126 | + if (player.id != id) { | ||
| 127 | + continue; | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + return player.on_player_ready(); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + throw new Error("player not found. id=" + id); | ||
| 134 | + } | ||
| 20 | </script> | 135 | </script> |
| 21 | </head> | 136 | </head> |
| 22 | <body> | 137 | <body> |
| @@ -38,10 +153,30 @@ | @@ -38,10 +153,30 @@ | ||
| 38 | </div> | 153 | </div> |
| 39 | </div> | 154 | </div> |
| 40 | <div class="container"> | 155 | <div class="container"> |
| 156 | + <div class="alert alert-info fade in"> | ||
| 157 | + <button type="button" class="close" data-dismiss="alert">×</button> | ||
| 158 | + <strong><span>Usage:</span></strong> <span>输入地址后点击播放按钮</span> | ||
| 159 | + </div> | ||
| 160 | + <div class="form-inline"> | ||
| 161 | + URL: | ||
| 162 | + <input type="text" id="txt_url" class="input-xxlarge" value=""></input> | ||
| 163 | + <button class="btn" id="btn_play">播放视频</button> | ||
| 164 | + </div> | ||
| 165 | + <div id="main_modal" class="modal hide fade"> | ||
| 166 | + <div class="modal-header"> | ||
| 167 | + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||
| 168 | + <h3>SrsPlayer</h3> | ||
| 169 | + </div> | ||
| 170 | + <div class="modal-body" id="player"> | ||
| 171 | + </div> | ||
| 172 | + <div class="modal-footer"> | ||
| 173 | + <button id="btn_pause" class="btn">暂停</button> | ||
| 174 | + <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button> | ||
| 175 | + </div> | ||
| 176 | + </div> | ||
| 41 | <hr> | 177 | <hr> |
| 42 | <footer> | 178 | <footer> |
| 43 | <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team © 2013</a></p> | 179 | <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team © 2013</a></p> |
| 44 | </footer> | 180 | </footer> |
| 45 | </div> | 181 | </div> |
| 46 | </body> | 182 | </body> |
| 47 | - |
| 1 | package | 1 | package |
| 2 | { | 2 | { |
| 3 | import flash.display.Sprite; | 3 | import flash.display.Sprite; |
| 4 | + import flash.display.StageAlign; | ||
| 5 | + import flash.display.StageScaleMode; | ||
| 6 | + import flash.events.Event; | ||
| 7 | + import flash.events.NetStatusEvent; | ||
| 8 | + import flash.external.ExternalInterface; | ||
| 9 | + import flash.media.Video; | ||
| 10 | + import flash.net.NetConnection; | ||
| 11 | + import flash.net.NetStream; | ||
| 12 | + import flash.ui.ContextMenu; | ||
| 13 | + import flash.ui.ContextMenuItem; | ||
| 14 | + import flash.utils.setTimeout; | ||
| 4 | 15 | ||
| 5 | public class srs_player extends Sprite | 16 | public class srs_player extends Sprite |
| 6 | { | 17 | { |
| 18 | + private var id:String = null; | ||
| 19 | + private var on_player_ready:String = null; | ||
| 20 | + | ||
| 21 | + private var url:String = null; | ||
| 22 | + | ||
| 23 | + private var conn:NetConnection = null; | ||
| 24 | + private var stream:NetStream = null; | ||
| 25 | + private var video:Video = null; | ||
| 26 | + | ||
| 7 | public function srs_player() | 27 | public function srs_player() |
| 8 | { | 28 | { |
| 29 | + if (!this.stage) { | ||
| 30 | + this.addEventListener(Event.ADDED_TO_STAGE, this.onAddToStage); | ||
| 31 | + } else { | ||
| 32 | + this.onAddToStage(null); | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + private function onAddToStage(evt:Event):void { | ||
| 37 | + this.stage.align = StageAlign.TOP_LEFT; | ||
| 38 | + this.stage.scaleMode = StageScaleMode.NO_SCALE; | ||
| 39 | + | ||
| 40 | + this.contextMenu = new ContextMenu(); | ||
| 41 | + this.contextMenu.hideBuiltInItems(); | ||
| 42 | + | ||
| 43 | + var flashvars:Object = this.root.loaderInfo.parameters; | ||
| 44 | + | ||
| 45 | + if (!flashvars.hasOwnProperty("id")) { | ||
| 46 | + throw new Error("must specifies the id"); | ||
| 47 | + } | ||
| 48 | + if (!flashvars.hasOwnProperty("on_player_ready")) { | ||
| 49 | + throw new Error("must specifies the on_player_ready"); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + this.id = flashvars.id; | ||
| 53 | + this.on_player_ready = flashvars.on_player_ready; | ||
| 54 | + | ||
| 55 | + flash.utils.setTimeout(this.onJsReady, 0); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + private function onJsReady():void { | ||
| 59 | + if (!flash.external.ExternalInterface.available) { | ||
| 60 | + trace("js not ready, try later."); | ||
| 61 | + flash.utils.setTimeout(this.onJsReady, 100); | ||
| 62 | + return; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + flash.external.ExternalInterface.addCallback("__play", this.js_call_play); | ||
| 66 | + flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop); | ||
| 67 | + flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause); | ||
| 68 | + flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume); | ||
| 69 | + | ||
| 70 | + var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id); | ||
| 71 | + if (code != 0) { | ||
| 72 | + throw new Error("callback on_player_ready failed. code=" + code); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + public function js_call_pause():int { | ||
| 77 | + if (this.stream) { | ||
| 78 | + this.stream.pause(); | ||
| 79 | + } | ||
| 80 | + return 0; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + public function js_call_resume():int { | ||
| 84 | + if (this.stream) { | ||
| 85 | + this.stream.resume(); | ||
| 86 | + } | ||
| 87 | + return 0; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + public function js_call_stop():int { | ||
| 91 | + if (this.stream) { | ||
| 92 | + this.stream.close(); | ||
| 93 | + this.stream = null; | ||
| 94 | + } | ||
| 95 | + if (this.conn) { | ||
| 96 | + this.conn.close(); | ||
| 97 | + this.conn = null; | ||
| 98 | + } | ||
| 99 | + if (this.video) { | ||
| 100 | + this.removeChild(this.video); | ||
| 101 | + this.video = null; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + return 0; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + public function js_call_play(url:String, _width:int, _height:int):int { | ||
| 108 | + this.url = url; | ||
| 109 | + trace("start to play url: " + this.url); | ||
| 110 | + | ||
| 111 | + js_call_stop(); | ||
| 112 | + | ||
| 113 | + this.conn = new NetConnection(); | ||
| 114 | + this.conn.client = {}; | ||
| 115 | + this.conn.client.onBWDone = function():void {}; | ||
| 116 | + this.conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 117 | + trace ("NetConnection: code=" + evt.info.code); | ||
| 118 | + if (evt.info.code != "NetConnection.Connect.Success") { | ||
| 119 | + return; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + stream = new NetStream(conn); | ||
| 123 | + stream.client = {}; | ||
| 124 | + stream.client.onMetaData = function(metadata:Object):void { | ||
| 125 | + var customItems:Array = [new ContextMenuItem("SrsPlayer")]; | ||
| 126 | + if (metadata.hasOwnProperty("server")) { | ||
| 127 | + customItems.push(new ContextMenuItem("Server: " + metadata.server)); | ||
| 128 | + } | ||
| 129 | + if (metadata.hasOwnProperty("contributor")) { | ||
| 130 | + customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor)); | ||
| 131 | + } | ||
| 132 | + contextMenu.customItems = customItems; | ||
| 133 | + }; | ||
| 134 | + stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 135 | + trace ("NetStream: code=" + evt.info.code); | ||
| 136 | + }); | ||
| 137 | + stream.play(url.substr(url.lastIndexOf("/"))); | ||
| 138 | + | ||
| 139 | + video = new Video(); | ||
| 140 | + video.width = _width; | ||
| 141 | + video.height = _height; | ||
| 142 | + video.attachNetStream(stream); | ||
| 143 | + video.smoothing = true; | ||
| 144 | + addChild(video); | ||
| 145 | + }); | ||
| 146 | + this.conn.connect(this.url.substr(0, this.url.lastIndexOf("/"))); | ||
| 147 | + | ||
| 148 | + return 0; | ||
| 9 | } | 149 | } |
| 10 | } | 150 | } |
| 11 | } | 151 | } |
-
请 注册 或 登录 后发表评论