rtmpt fallback if rtmp not working ?

This thread may refer to an older version of JW Player! Check our articles for the most up-to-date information.
This Q&A thread was imported from our previous system and could apply to an older product.
  • Hi,

    i'm try to implement rtmpt fallback with rtmp , but it doesn't work.

    I can force rtmp or rtmpt in the player, but it can be better to just use rtmp, and if a user cannot read it (proxy by exemple), the player try automaticly rtmpt.

    for the next version of the player perhaps ;)

  • I am using RTMP protocol for connection over port 80, It is working fine out of firewall but under fire wall it is not able to connect with server.

    I want to use RTMPT protocol instead of rtmp protocol,

    Question : if firewall will not have a tunneling proxy, will firewall allow rtmpt connection ?

    Up Down 1 rated
  • my mail id is : pankaj.cdac@gmail.com please reply me

    Up Down 0 rated
  • I have no experience with this, but can do some test. I just installed a copy of Wowza, so will check!

    Up Down 0 rated
  • Panjaj, just use rtmpt://x.x.x.x:80 in your player parameter instead rtmp://

    Up Down 0 rated
  • any news?

    Up Down 0 rated
  • /me would like to know too

    Up Down 0 rated
  • for now i use port 80 for RTMP with RED5 but i understand it is not as good as RTMPT for "application firewalls" or firewalls that "understand" the packets?

    Up Down 0 rated
  • ran,

    with rtmpt, you can use http proxy in enterprise for exemple.

    The firewall can block the port 80, and if you can only surf on internet via a proxy, so rtmpt is the only solution.

    Up Down 0 rated
  • Hi all,

    I'm using wowza to stream my videos and I just fined a post about connection rollover.

    Is there a way to add this to JW player?


    Up Down 0 rated
  • Hi Jeroen,

    here is my rtmp fallback implementation, I think it can be used "as is".

    You only have to join your streamer urls separated with a pipe (|) (rtmp://url/app|rtmpt://url2/app ...)

    bc.. /**
    * Wrapper for playback of video streamed over RTMP.
    * All playback functionalities are cross-server (FMS, Wowza, Red5), with the exception of:
    * - The SecureToken functionality (Wowza).
    * - The FCSubscribe functionality (Limelight/Akamai FMS).
    * - getStreamLength / checkBandwidth (FMS3).
    package com.jeroenwijering.models {

    import com.jeroenwijering.events.*;
    import com.jeroenwijering.models.ModelInterface;
    import com.jeroenwijering.player.Model;
    import com.jeroenwijering.utils.NetClient;
    import com.jeroenwijering.utils.TEA;

    import flash.display.DisplayObject;
    import flash.events.*;
    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;

    public class RTMPModel implements ModelInterface {

    /** reference to the model. **/
    private var model:Model;
    /** Video object to be instantiated. **/
    private var video:Video;
    /** NetConnection object for setup of the video stream. **/
    private var connection:NetConnection;
    /** NetStream instance that handles the stream IO. **/
    private var stream:NetStream;
    /** Sound control object. **/
    private var transform:SoundTransform;
    /** Interval ID for the time. **/
    private var timeinterval:Number;
    /** Timeout ID for live stream subscription pings. **/
    private var timeout:Number;
    /** Metadata have been received. **/
    private var metadata:Boolean;

    /** NetConnection connection timer. **/
    private var ncConnectTimer:Number = 0;
    /** NetConnection connection timeout (ms). **/
    private var ncConnectTimeout:Number = 3000; // 3 seconds
    /** NetConnection connection try. **/
    private var ncTryIndex:Number = 0;
    /** Streamer list (splited string, each streamer is separated with a pipe |). **/
    private var ncStreamers:Array = new Array();

    /** Constructor; sets up the connection and display. **/
    public function RTMPModel(mod:Model):void {
    model = mod;
    connection = new NetConnection();
    connection.objectEncoding = ObjectEncoding.AMF0;
    connection.client = new NetClient(this);
    video = new Video(320,240);
    transform = new SoundTransform();
    model.config['mute'] == true ? volume(0): volume(model.config['volume']);

    ncStreamers = model.playlist[model.config['item']]['streamer'].split("|");

    /** Catch security errors. **/
    private function errorHandler(evt:ErrorEvent):void {

    /** Extract the correct rtmp syntax from the file string. **/
    private function getID(url:String):String {
    var ext:String = url.substr(-4);
    if(ext == '.mp3') {
    return 'mp3:'+url.substr(0,url.length-4);
    } else if(ext == '.mp4' || ext == '.mov' || ext == '.aac' || ext == '.m4a') {
    return 'mp4:'+url;
    } else if (ext == '.flv') {
    return url.substr(0,url.length-4);
    } else {
    return url;

    /** Reset connection timer. **/
    function clearConnectTimer():void {
    if (ncConnectTimer != 0)
    ncConnectTimer = 0;

    /** Reset connection timer and try next available url. **/
    function tryReconnect():void {

    /** Try to connect to server with next available url. **/
    function tryConnect():void {

    var url:String = "";
    if(ncTryIndex < ncStreamers.length)
    url = ncStreamers[ncTryIndex];
    model.sendEvent(ModelEvent.ERROR,{message:"Failed to connect after "+ncTryIndex+" tries"});

    if (url.length > 0)
    ncConnectTimer = setInterval(tryReconnect, ncConnectTimeout);

    /** Load content. **/
    public function load():void {

    /** Catch noncritical errors. **/
    private function metaHandler(evt:ErrorEvent):void {

    /** Get metadata information from netstream class. **/
    public function onData(dat:Object):void {
    if(dat.type == 'metadata' && !metadata) {
    if(dat.width) {
    video.width = dat.width;
    video.height = dat.height;
    if(model.playlist[model.config['item']]['start'] > 0) {
    metadata = true;
    } else if(dat.type == 'complete') {
    } else if(dat.type == 'fcsubscribe') {
    if(dat.code == "NetStream.Play.StreamNotFound" ) {
    model.sendEvent(ModelEvent.ERROR,{message:"Subscription failed: "+model.playlist[model.config['item']]['file']});
    }else if(dat.code == "NetStream.Play.Start") {

    /** Pause playback. **/
    public function pause():void {

    /** Resume playing. **/
    public function play():void {
    timeinterval = setInterval(timeHandler,100);

    /** Change the smoothing mode. **/
    public function quality(qua:Boolean):void {
    if(qua == true) {
    video.smoothing = true;
    video.deblocking = 3;
    } else {
    video.smoothing = false;
    video.deblocking = 1;

    /** Change the smoothing mode. **/
    public function seek(pos:Number):void {
    if(model.config['state'] == ModelStates.PAUSED) {
    } else {

    /** Set streaming object **/
    public function setStream():void {
    var url = getID(model.playlist[model.config['item']]['file']);
    stream = new NetStream(connection);
    stream.bufferTime = model.config['bufferlength'];
    stream.client = new NetClient(this);
    stream.soundTransform = transform;
    var res:Responder = new Responder(streamlengthHandler);
    timeinterval = setInterval(timeHandler,100);

    /** Receive NetStream status updates. **/
    private function statusHandler(evt:NetStatusEvent):void {
    switch (evt.info.code) {
    case 'NetConnection.Connect.Success':
    if(evt.info.secureToken != undefined) {
    if(model.config['subscribe']) {
    timeout = setInterval(subscribe,2000,getID(model.playlist[model.config['item']]['file']));
    } else {
    case 'NetStream.Seek.Notify':
    timeinterval = setInterval(timeHandler,100);
    case 'NetConnection.Connect.Rejected':
    if(evt.info.ex.code == 302) {
    model.playlist[model.config['item']]['streamer'] = evt.info.ex.redirect;
    case 'NetStream.Play.StreamNotFound':
    model.sendEvent(ModelEvent.ERROR,{message:"Stream not found: "+model.playlist[model.config['item']]['file']});
    case 'NetConnection.Connect.Failed':

    /** Destroy the stream. **/
    public function stop():void {
    if(stream) { stream.close(); }

    /** Get the streamlength returned from the connection. **/
    private function streamlengthHandler(len:Number):void {

    /** Akamai & Limelight subscribes. **/
    private function subscribe(nme:String):void {

    /** Interval for the position progress **/
    private function timeHandler():void {
    var bfr = Math.round(stream.bufferLength/stream.bufferTime*100);
    var pos = Math.round(stream.time*10)/10;
    var dur = model.playlist[model.config['item']]['duration'];
    if(bfr < 95 && pos < Math.abs(dur-stream.bufferTime-1)) {
    if(model.config['state'] != ModelStates.BUFFERING) {
    } else if (model.config['state'] == ModelStates.BUFFERING) {

    /** Set the volume level. **/
    public function volume(vol:Number):void {
    transform.volume = vol/100;
    if(stream) {
    stream.soundTransform = transform;



    Thanks to Charlie from Wowza


    Up Down 0 rated
  • Thanks for posting this liilo, but I can get it to compile. Getting error -
    1172: Definition com.jeroenwijering.utils:TEA could not be found.

    Up Down 0 rated
  • sorry, forget my last post. Think I must have different source.

    Up Down 0 rated

  • Does the current version (JW FLV Media Player 4.3) have this fallback / rollover code?

    If not, are there plans to "officially" implement it?

    Up Down 0 rated
  • I'm not sure if it's still relevant to this thread, but if you still need an answer take a look at the bottom of this page:

    Flash automatically attempts rtmpt fallback when using the rtmp protocol (so long as your media server supports the given port/protocol - e.g. Wowza requires you to alter the VHosts.xml to listen on port 80 and/or 443 for the rtmpt). No custom code is required

    Up Down 0 rated
  • Hey, that is interesting. Can someone with RTMP experience confirm this though? Do fallbacks also happen fast and not after, say, 60 seconds?

    Up Down 0 rated
  • @Jeroen, I just did some rough testing with a stopwatch and a program called Active Ports and it appears the connections timeout after about 20-25 seconds so by the time the Flash Player has tried RTMP ports 1935, 443, and then 80 and gets to try RTMPT over port 80, more than a minute has passed. I can't imagine any user watching a spinning wheel for a minute waiting for a video. Also, if you specify a port in the RTMP URL, there is no automatic fallback at all in the Flash Player in these cases.

    It would be a nice addition to JW Player if it would fall back to RTMPT over port 80 when a RTMP port is specified. It would be great if you could specify a fallback/timeout value through a FlashVar as well. For example, if you're not running a webserver on your streaming server, the most reliable option, as far as accounting for incoming and outgoing firewalls, is to run your streaming server on port 80. However, if you specify :80 in your RTMP URL, no fallback to RTMPT occurs.

    Up Down 0 rated
  • Hi

    We are trying to get this to work for us but have had no luck.

    We use the Wowza Server and I have read the post.

    1. How do we set up the code in the JW Player

    2. Do we need to add code to the JW Player

    3. Also, if anyone is familar with Wowza, what section of the VHost.xml needs editing

    Here is what we are using right now:
    bc.. <script type="text/javascript">
    var s1 = new SWFObject("player.swf","ply","640","381","9","#FFFFFF");

    Any help would be great

    Up Down 0 rated
  • I have tried now om my network. Running Wowza 1.7.
    The wowza server has been configured to listen to port 80 and 1935,

    I did block port 1935 in my firewall/router (Client side).

    When trying to connect with JW player 4.4.198 it times out and gives me: Server not found error.

    I have to change to streamer=rtmp://woza.server.com:80/files.

    Why isn't there an automatic rollover for this ??

    Up Down 0 rated
  • *fsadfsdf*

    Up Down 0 rated
  • Jeroen,
    in ticket #311 you reference an older KB article which says the order is rtmp:1935, rtmp:443, rtmp:80, rtmpt:80.
    In practice, this doesn't work very well - we use FAVideo and know of corporate networks where you can't get video at all or only after a 45 sec delay if the firewall doesn't explicitly reject the connections.
    This is why NCManager (VideoPlayer, used in FLVPlayback) connects in the order rtmp:1935, rtmp:443, rtmpt:80, rtmps:443. These are opened in parallel (with a short delay) and the first connection that succeeds is used.

    Fore more details, the source is here: http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/videoClasses/NCManager.as

    Up Down 0 rated
  • Hey, I took Christian's code & used it for a video publisher, it was pretty easy to do and works very well.

    As suggested by JW I had a look at making a plugin which did this, but couldn't see how to hook in to the connect() event and run that logic through the NCManager instead of default flash NC .....
    so am hacking into the player ...
    any suggestions as to which event (if any) suitable to hook in to and do this, please let me know nick.p.doyle at gmail dot com

    Up Down 0 rated
  • Also - Christian's code tries the methods almost in parallel, so is very fast to find which one works ...
    (it's also quite simple & elegant - nice one dude)

    Up Down 0 rated
  • Sorry, the code I actually used was from this article by Will Law of Hostcast:

    Up Down 0 rated
  • Hi

    has the issue of rtmpt been solved regarding the delay. We are tunneling and find that there is a 6 moniute delate before JW player actually plays the video. Is there any way of connecting directly to port 80 ? We are using FMS.

    Any help appreciated.



    Up Down 0 rated
  • Any more info on fallback plugin?

    Had a large live event this weekend.

    Had to set up two landing sites one for port 80 and one for 1935. Most of the users could use 1935 just fine.

    But on some corporate networks port 80 was the only choice.

    Up Down 0 rated
  • I thing we have to create a petition for this issue ;-)

    Up Down 0 rated
  • I've just been bitten by this issue. We're using an rtmp stream that our client cannot view behind their firewall. Changing the URL to rtmpt on port 80 makes it work.

    Like Nick Doyle above, I tried to see if there was a way to override the RTMPModel class with a smarter one and have a plugin plug it in it at runtime. It looks like the Model object is off limits to plugins...everything is declared private so there's no way I can see to access it from the View.

    Is there a path here for a plugin developer that I'm missing? Or si there a change that can be made in a future version of the player that would allow replacement or extension of the Model objects?

    Up Down 0 rated
  • I'd be interested in a plugin or workaround to this problem, so any progress on this I'd love to know. martin (at) cumbrialive.tv - Cheers

    Up Down 0 rated
  • I need help here as well.
    streamer:'rtmpt://fms.server.com/app', does not work for me. neither does

    Up Down 0 rated
  • Running into the same problem. Since I have my webserver running on port 80, I have Wowza configured on port 1935. One of our users is behind a firewall that is blocking this. How can I get it to play? I've tried this but get errors:


    Up Down 0 rated
  • See Ticket #311


    Up Down 0 rated
  • http://developer.longtailvideo.com/trac/ticket/513

    Its on the road map but not on high priority :(

    Up Down 0 rated
  • I see the ticket is now closed. Is anyone on the case with building this?

    Up Down 0 rated
  • We haven’t gotten any volunteers to build this plugin. If anyone’s interested in writing this plugin, please contact plugins [at] longtailvideo [dot] com.

    Up Down 0 rated
  • We’ve gotten a fair bit of requests for it now, so we’ll go ahead and implement such a fallback in the player. I underestimated the need for it.

    There’s already a <a href="http://developer.longtailvideo.com/trac/ticket/951">ticket in the developer site</a> for the next release. Please let Pablo and me know if you have any specific wishes or quirks you want to bring to our attention.

    Up Down 0 rated
  • Hi,

    I think I got it running by following Flowplayer implementation.
    Here are the functions I changed (against JW player 5.0 as I have problems displaying messages with latest versions).
    RTMPMediaProvider.as :
    bc.. /**
    * Wrapper for playback of _video streamed over RTMP.
    * All playback functionalities are cross-server (FMS, Wowza, Red5), with the exception of:
    * - The SecureToken functionality (Wowza).
    * - getStreamLength / checkBandwidth (FMS3).
    package com.longtailvideo.jwplayer.media {
    import com.jeroenwijering.events.*;
    import com.longtailvideo.jwplayer.events.MediaEvent;
    import com.longtailvideo.jwplayer.model.PlayerConfig;
    import com.longtailvideo.jwplayer.model.PlaylistItem;
    import com.longtailvideo.jwplayer.player.PlayerState;
    import com.longtailvideo.jwplayer.utils.NetClient;
    import com.longtailvideo.jwplayer.utils.TEA;

    import flash.events.*;
    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;

    public class RTMPMediaProvider extends MediaProvider {
    /** Video object to be instantiated. **/
    protected var _video:Video;
    /** NetConnection object for setup of the _video _stream. **/
    protected var _connection:NetConnection;

    private var _connector1:Connector;
    private var _connector2:Connector;
    private var _connectionClient:Object;

    /** Loader instance that loads the XML file. **/
    private var _loader:URLLoader;
    /** NetStream instance that handles the _stream IO. **/
    protected var _stream:NetStream;
    /** Sound control object. **/
    protected var _transformer:SoundTransform;
    /** Save the location of the XML redirect. **/
    private var _smil:String;
    /** Save that the _video has been _started. **/
    protected var _started:Boolean;
    /** ID for the position _positionInterval. **/
    protected var _positionInterval:Number;
    /** Save that a file is _unpublished. **/
    protected var _unpublished:Boolean;
    /** Whether the buffer has filled **/
    private var _bufferFull:Boolean;

    public function RTMPMediaProvider() {

    /** Constructor; sets up the connection and display. **/
    public override function initializeMediaProvider(cfg:PlayerConfig):void {
    // _connection = new NetConnection();
    // _connection.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);
    // _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
    // _connection.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
    // _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
    // _connection.objectEncoding = ObjectEncoding.AMF0;
    // _connection.client = new NetClient(this);
    _connectionClient = new NetClient(this);
    _loader = new URLLoader();
    _loader.addEventListener(Event.COMPLETE, loaderHandler);
    _loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
    _loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
    _video = new Video(320, 240);
    _video.smoothing = config.smoothing;
    _transformer = new SoundTransform();

    bc.. /** Finalizes the loading process **/
    private function finishLoad():void {
    var ext:String = item.file.substr(-4);
    if (ext == '.mp3'){
    media = null;
    } else if (!media) {
    media = _video;
    var parts:Array = getUrlParts(item.streamer);
    _connector1 = new Connector((parts[0] == 'rtmp' ? 'rtmp' : 'rtmpe') + '://' + parts[1], _connectionClient, onConnectorSuccess, onConnectorFailure);
    _connector2 = new Connector((parts[0] == 'rtmp' ? 'rtmpt' : 'rtmpte') +'://' + parts[1], _connectionClient, onConnectorSuccess, onConnectorFailure);

    doConnect(_connector1, "best", ObjectEncoding.AMF0);

    // RTMPT connect is started after 250 ms
    var delay:Timer = new Timer( 250, 1);
    delay.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void {
    doConnect(_connector2, "best", ObjectEncoding.AMF0);

    config.mute == true ? setVolume(0) : setVolume(config.volume);

    private function doConnect(connector:Connector, proxyType:String, objectEncoding:uint):void {
    connector.connect(proxyType, objectEncoding, null);

    private function onConnectorSuccess(connector:Connector, connection:NetConnection, evt:NetStatusEvent):void {
    if (_connection) return;
    _connection = connection;
    if (connector == _connector2 && _connector1) {
    } else if (_connector2) {

    private function onConnectorFailure(evt:NetStatusEvent):void {
    if (isFailedOrNotUsed(_connector1) && isFailedOrNotUsed(_connector2)) {

    private function isFailedOrNotUsed(connector:Connector):Boolean {
    if (! connector) return true;
    return connector.failed;
    private function getUrlParts(url:String):Array {
    var pos:int = url.indexOf('://');
    if (pos > 0) {
    return [url.substring(0, pos), url.substring(pos + 3)];
    return null;

    And Connector.as :
    bc.. package com.longtailvideo.jwplayer.media {
    import flash.events.NetStatusEvent;
    import flash.net.NetConnection;

    import flash.utils.setTimeout;

    import com.longtailvideo.jwplayer.utils.Logger;

    public class Connector {
    private var _url:String;
    private var _successListener:Function;
    private var _connectionClient:Object;
    private var _connection:NetConnection;
    private var _failureListener:Function;
    private var _failed:Boolean;

    public function Connector(url:String, connectionClient:Object, onSuccess:Function, onFailure:Function) {
    _url = url;
    _connectionClient = connectionClient;
    _successListener = onSuccess;
    _failureListener = onFailure;
    _failed = false;
    Logger.log("created with connection client " + _connectionClient);

    public function connect(proxyType:String, objectEncoding:uint, connectionArgs:Array):void {
    Logger.log(this +"::connect() using proxy type '" + proxyType + "'" + ", object encoding " + objectEncoding);
    if (_successListener == null) {
    Logger.log(this + ", this connector has been stopped, will not proceed with connect()");
    _connection = new NetConnection();
    _connection.proxyType = proxyType;
    _connection.objectEncoding = objectEncoding;

    Logger.log("using connection client " + _connectionClient);
    if (_connectionClient) {
    _connection.client = _connectionClient;
    _connection.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus);

    Logger.log("netConnectionUrl is " + _url);
    if (connectionArgs && connectionArgs.length > 0) {
    _connection.connect.apply(_connection, [ _url ].concat(connectionArgs));
    } else {

    private function onConnectionStatus(event:NetStatusEvent):void {
    Logger.log(this + "::onConnectionStatus() " + event.info.code);

    if (event.info.code == "NetConnection.Connect.Success") {
    if (_successListener != null) {
    _successListener(this, _connection, event);
    } else {
    Logger.log("this connector is stopped, will not call successListener");


    if (event.info.code == "NetConnection.Connect.Rejected" && event.info.ex && event.info.ex.code == 302) {
    Logger.log("starting a timeout to connect to a redirected URL " + event.info.ex.redirect);
    Logger.log("connecting to a redirected URL " + event.info.ex.redirect);
    }, 100);

    if (["NetConnection.Connect.Failed", "NetConnection.Connect.Rejected", "Ne

    Up Down 0 rated
  • I was wondering if protocol fallback has been implemented in jwplayer yet?

    We are using jwplayer 5.2 at the moment (in combination with Wowza) and would like to open streams with rtmp on port 1935. But for those with stateful proxys/firewalls (or other blocks) fallback to rtmpt on port 80 would be very welcome.

    Up Down 0 rated
  • @Akke-

    This feature has been implemented in the most recent build of the player, but it has not yet been released (it will be included in the 5.3 release). If you’d like to check out a preview of the 5.3 player, you can download the most recent version at:


    Up Down 0 rated
  • any ideas on when 5.3 will be released with this auto-fallback (RTMPT) feature? i too am needing this pretty quickly. as a heads up, perhaps someone can provide the necessary syntax in regards to flashvars or the streamer var to make the fallback work?

    many thanks!

    Up Down 0 rated
  • @Steven -

    The 5.3 beta has been released, and will go into testing soon. You can grab the beta here:


    Up Down 0 rated

This QA is closed.

Still don't have JW Player? Get It Here