rtmpconnection.lzx
<library>
<class name="rtmpconnection">
<doc>
<tag name="shortdesc"><text>Allows connections to RTMP servers</text></tag>
<text>
<p><tagname>rtmpconnection</tagname> allows applications to connect to RTMP servers, like http://osflash.org/red5 or http://www.wowzamedia.com/. Note that you'll need a server running with the appropriate URLs set up for this example to work.</p>
<example><programlisting class="code">
<canvas>
<rtmpconnection src="rtmp://localhost:1935/simplevideostreaming/" autoconnect="true"/>
<videoplayer url="Extremists.flv" type="rtmp" autoplay="true" width="320" height="240"/>
</canvas>
</programlisting></example>
</text>
</doc>
<passthrough when="$as3">
import flash.net.NetConnection;
import flash.events.ErrorEvent;
import flash.events.StatusEvent;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.AsyncErrorEvent;
</passthrough>
<attribute name="autoconnect" value="true
" type="boolean"/>
<attribute name="status" value="disconnected
" type="string"/>
<attribute name="stage" value="0
" type="number"/>
<attribute name="_nc" value="null
" type="expression"/>
<attribute name="src" value="
" type="string"/>
<attribute name="connectionparams" value="null
" type="expression"/>
<attribute name="altsrc" value="
" type="string"/>
<attribute name="_usealtsrc" value="false
" type="boolean"/>
<attribute name="connectiontimeout" value="3000
" type="number"/>
`
<attribute name="debug" value="false
"/>
<attribute name="connections" value="null
" type="expression" allocation="class"/>
<attribute name="objectencoding" value="0
" type="number"/>
<event name="onconnect"/>
<event name="onerror"/>
<method name="init">
super.init();
// Store new RTMP connections in lz.rtmpconnection.connections. If no
// name is set for an rtmpconnection use "_default". Other real-time
// objects will use the lz.rtmpconnection.connections["_default"] NetConnection
if (this.name == null) {
this.name = "_default";
}
if (lz.rtmpconnection.connections != null && lz.rtmpconnection.connections[this.name] != null) {
if ($debug) {
if (this.name == "_default") {
Debug.warn("A default RTMP connection already exists, please name connections if you use more than one");
} else {
Debug.warn("An RTMP connection already exists with the name '%s': %w", this.name, lz.rtmpconnection.connections[this.name]);
}
}
}
if (lz.rtmpconnection.connections == null) {
lz.rtmpconnection.connections = {};
if (this.name != "_default")
lz.rtmpconnection.connections._default = this;
}
lz.rtmpconnection.connections[this.name] = this;
if (this.debug) {
// This is the way a function is called by the remote Interface has
// to be implemented ...
/**
this._nc.setId = function(id) {
_root.Debug.write("########## Method called by rtmp Server");
_root.Debug.write("---------------> id: ", id);
}
**/
}
/** the following code should work now, but it hasn't
been tested, so I'll leave it commented out -sa
this._nc.__resolve = function(name) {
//_root.Debug.write("__resolve " , name, typeof(this[name]));
//_root.Debug.write(" arguments.callee.name " ,
// arguments.callee.name);
if (typeof(this.t[name]) == "function") {
this.t[name].apply(arguments);
}
};
**/
if (this.autoconnect) {
this.connect();
}
</method>
<method name="_onSecurityError" args="error">
var errstr = error + '';
if ($debug) Debug.warn("rtmpconnection _onSecurityError() " + errstr);
if (this.onerror.ready) {
this.onerror.sendEvent(errstr);
}
</method>
<method name="_createconnection">
this.setAttribute('_nc', new NetConnection());
if ($as3) {
this._nc.objectEncoding = this.objectencoding;
this._nc.addEventListener(NetStatusEvent.NET_STATUS, this._onStatus);
this._nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this._onSecurityError);
this._nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this._onSecurityError);
this._nc.client = this;
} else {
// $swf8 or $swf7
// For some reason this cannot be done as a closure (in FP7).
// See bug lpp-2197.
this._nc.t = this;
this._nc.onStatus = function(info) {
this.t._onStatus(info);
};
}
</method>
<method name="onBWDone"/>
<method name="connect">
//Debug.write("rtmpconnection.connect, stage", this.stage);
if (this.stage > 0) {
return; // already connected or connecting
}
var src = this._usealtsrc ? this.altsrc : this.src;
if (src == 'null') src = null;
if (this.debug) {
if ($debug) Debug.write("initiating connection to ", src);
}
if ($debug) {
if (src == "") {
Debug.write("no src url defined for", this);
return;
} else if (typeof(src) != "string") {
Debug.write("src", src, "must be a string in", this);
return;
}
}
this._connecturl = src;
this._createconnection();
this._doconnect();
this.setAttribute("status", "connecting");
this.setAttribute("stage", 1);
if (! this['_connectionTimeoutDel']) this._connectionTimeoutDel = new LzDelegate(this, '_handleConnectionTimeout');
lz.Timer.addTimer( this._connectionTimeoutDel, this.connectiontimeout );
</method>
<method name="_doconnect" args="">
this._nc.connect(src,this.connectionparams);
</method>
<method name="_handleConnectionTimeout" args="ignore=null">
if (this.stage < 2) {
this.setAttribute("status", "timed out");
this.setAttribute("stage", 0);
this._handleConnectionFailure("timed out");
}
</method>
<method name="_handleConnectionFailure" args="msg">
this._nc.close();
if (this.debug) {
if ($debug) Debug.warn("error connecting to", this._connecturl, ":", msg);
}
if (! this._usealtsrc && this.altsrc != '') {
// attempt connection to altsrc
this._usealtsrc = true;
this.connect();
} else if (this._connecturl == altsrc) {
// reset so subsequent calls to connect() will try again.
this._usealtsrc = false;
}
</method>
<method name="_onStatus" args="evt">
if ($as3) evt = evt.info;
var code = evt.code;
// only used for debugging
var description = evt['description'] ? evt.description : "";
//Debug.write(evt);
//Debug.write("rtmpconnection", this, "_onStatus", code, description);
if (this.debug) {
if ($debug) Debug.write("rtmpconnection", this, "_onStatus", code);
}
var msg = "";
var s = this.stage;
switch (code) {
case "NetConnection.Connect.AppShutdown": {
// The application has been shut down
// (for example, if the application is out of memory
// resources and must be shut down to prevent the
// server from crashing) or the server has been shut down.
msg = "disconnected (error)";
s = 0;
break;
}
case "NetConnection.Connect.Closed": {
// The connection was successfully closed.
msg = "disconnected";
s = 0;
break;
}
case "NetConnection.Connect.Failed": {
// The connection attempt failed;
// for example, the server is not running.
msg = "connection failed";
s = 0;
break;
}
case "NetConnection.Connect.Rejected": {
// The client does not have permission to connect
// to the application, or the application expected
// different parameters from those that were passed,
// or the application specifically rejected the client.
msg = "connection rejected";
s = 0;
break;
}
case "NetConnection.Connect.Success": {
// The connection attempt succeeded.
msg = "connected";
s = 2;
break;
}
default: {
msg = code;
break;
}
}
this.setAttribute("status", msg);
this.setAttribute("stage", s);
lz.Timer.removeTimer(this._connectionTimeoutDel);
if (s == 2) {
if (this.debug) {
if ($debug) Debug.write("connected to " + this._connecturl);
}
if (this.onconnect.ready) {
this.onconnect.sendEvent();
}
} else if (msg != 'disconnected') {
// disconnection isn't a failure.
this._handleConnectionFailure(msg);
}
</method>
<method name="callMethod" args="func, obj, params">
if (this.debug) {
if ($debug) Debug.write("callMethod: func, obj, params", func, obj, params);
}
this._nc.call(func, obj, params);
</method>
</class>
</library>