winlin

add srs player

@@ -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 &copy; 2013</a></p> 179 <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team &copy; 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 }