1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00
srs/trunk/research/players/srs_player/src/Player.as
2016-08-02 16:52:23 +08:00

210 lines
No EOL
6.7 KiB
ActionScript

package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageDisplayState;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.FullScreenEvent;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.TimerEvent;
import flash.external.ExternalInterface;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.URLVariables;
import flash.system.Security;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.utils.setTimeout;
import flashx.textLayout.formats.Float;
/**
* common player to play rtmp/flv stream,
* use system NetStream.
*/
public class Player
{
// refresh every ts_fragment_seconds*M3u8RefreshRatio
public static var M3u8RefreshRatio:Number = 0.3;
// parse ts every this ms.
public static var TsParseAsyncInterval:Number = 80;
private var js_id:String = null;
// play param url.
private var user_url:String = null;
private var media_stream:NetStream = null;
private var media_conn:NetConnection = null;
private var owner:srs_player = null;
public function Player(o:srs_player) {
owner = o;
}
public function init(flashvars:Object):void {
this.js_id = flashvars.id;
}
public function stream():NetStream {
return this.media_stream;
}
private function dumps_object(obj:Object):String {
var smr:String = "";
for (var k:String in obj) {
smr += k + "=" + obj[k] + ", ";
}
return smr;
}
public function play(url:String):void {
owner.on_player_status("init", "Ready to play");
var streamName:String;
this.user_url = url;
this.media_conn = new NetConnection();
this.media_conn.client = {};
this.media_conn.client.onBWDone = function():void {};
this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
log("NetConnection: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
+ ", info is " + dumps_object(evt.info));
if (evt.info.hasOwnProperty("data") && evt.info.data) {
owner.on_player_metadata(evt.info.data);
}
// reject by server, maybe redirect.
if (evt.info.code == "NetConnection.Connect.Rejected") {
// RTMP 302 redirect.
if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) {
streamName = url.substr(url.lastIndexOf("/") + 1);
url = evt.info.ex.redirect + "/" + streamName;
log("Async RTMP 302 Redirect to: " + url);
// notify server.
media_conn.call("Redirected", null, evt.info.ex.redirect);
// do 302.
owner.on_player_302(url);
return;
}
owner.on_player_status("rejected", "Server reject play");
close();
}
if (evt.info.code == "NetConnection.Connect.Success") {
owner.on_player_status("connected", "Connected at server");
}
if (evt.info.code == "NetConnection.Connect.Closed") {
close();
}
if (evt.info.code == "NetConnection.Connect.Failed") {
owner.on_player_status("failed", "Connect to server failed.");
close();
}
// TODO: FIXME: failed event.
if (evt.info.code != "NetConnection.Connect.Success") {
return;
}
if (url.indexOf(".m3u8") > 0) {
media_stream = new HlsNetStream(M3u8RefreshRatio, TsParseAsyncInterval, media_conn);
} else {
media_stream = new NetStream(media_conn);
}
media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
log("NetStream: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
+ ", info is " + dumps_object(evt.info));
if (evt.info.code == "NetStream.Play.Start") {
owner.on_player_status("play", "Start to play stream");
}
if (evt.info.code == "NetStream.Play.StreamNotFound") {
owner.on_player_status("rejected", "Stream not found");
close();
}
if (evt.info.code == "NetStream.Video.DimensionChange") {
owner.on_player_dimension_change();
} else if (evt.info.code == "NetStream.Buffer.Empty") {
owner.on_player_buffer_empty();
} else if (evt.info.code == "NetStream.Buffer.Full") {
owner.on_player_buffer_full();
}
// TODO: FIXME: failed event.
});
// setup stream before play.
owner.on_player_before_play();
if (url.indexOf("http") == 0) {
media_stream.play(url);
} else {
streamName = url.substr(url.lastIndexOf("/") + 1);
media_stream.play(streamName);
}
owner.on_player_play();
});
if (url.indexOf("http") == 0) {
this.media_conn.connect(null);
} else {
var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/"));
streamName = url.substr(url.lastIndexOf("/") + 1);
// parse vhost from stream query.
if (streamName.indexOf("?") >= 0) {
var uv:URLVariables = new URLVariables(user_url.substr(user_url.indexOf("?") + 1));
var domain:String = uv["domain"];
if (!domain) {
domain = uv["vhost"];
}
if (domain) {
tcUrl += "?vhost=" + domain;
}
}
this.media_conn.connect(tcUrl);
}
}
public function close():void {
var notify:Boolean = false;
if (this.media_stream) {
this.media_stream.close();
this.media_stream = null;
notify = true;
}
if (this.media_conn) {
this.media_conn.close();
this.media_conn = null;
notify = true;
}
if (notify) {
owner.on_player_status("closed", "Server closed.");
}
}
private function log(msg:String):void {
Utility.log(js_id, msg);
}
}
}