views:

132

answers:

4

Hi

I have some FLV video files to be reproduced sequentially by a Flash video player. Suppose v1.flv and v2.flv. I want the player to start playing v2.flv once v1.flv has reached the end. According to this forum, the onPlayStatus does not fire in progressive FLVs. What can be done? A snippet of what I am trying below:

public class MyClass extends Sprite {
    private var nc : NetConnection;
    private var ns : NetStream;
    private var vid : Video;
    private var vidURL : String = "v1.flv";

    public function MyClass() {
        var nsClient:Object = {};
        nsClient.onPlayStatus = client_onPlayStatus;

        nc = new NetConnection();
        nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
        nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        nc.connect(null);

        ns = new NetStream(nc);
        ns.play(vidURL);
        ns.client = nsClient;

        vid = new Video();
        vid.attachNetStream(ns);

        addChild(vid);
    }

    private function netStatusHandler(event : NetStatusEvent) : void {
        trace(event.info.code);
        switch(event.info.code) {
            case "NetConnection.Connect.Success":
                trace("Loaded stream: " + vidURL);
                break;
            case "NetStream.Play.StreamNotFound":
                trace("Stream not found: " + vidURL);
                break;
            default:
        }
    }

    private function client_onPlayStatus(event:Object) : void {
        trace("status=" + event.info.code);
    }
}

The only text that shows up in the trace output is:

NetConnection.Connect.Success
Loaded stream: /path/to/v1.flv

Any help will be appreciated!

A: 

This blog post seem to cover just that

Charlie boy
This does not work either but might go into a solution. I am adapting it. I have no metadata in these FLVs so the duration is not given. Is there a way I can calculate the duration?
mga
A: 

you could also try the osmf framework , adobe's offer to streamline flash media delivery. osmf implements sequential playing out of the box. http://www.osmf.org/developers.html

check this blog for info & sample code http://www.rblank.com/

PatrickS
+1  A: 

You can still do that with one additional netStatus pseudo-event: when the video stops, check the time.

switch(event.info.code) {
    (...)
    case "NetStream.Play.Stop":
        if (ns.time >= nsClient.nsInfo.duration - 0.1) trace ("video has finished");
        break;
}

Caveats:

  1. You'll have to wait for the metadata information (that's 'nsInfo' in the example) before you have the duration:

    // On nsClient
    public function onMetaData(info:Object):void {
        nsInfo = info;
    }
    
  2. It's not very precise, hence the "-0.1" to make the time comparison safer

zeh
the thing is that the `NetStream.Play.Stop` event is not being fired either... as I mentioned in the question, the only output being shown is for `NetConnection.Connect.Success`... the output I show there is for the complete duration of `v1.flv`
mga
That forum post is old - it may have changed. I say this because I use this very event to detect the end of my progressive loaded FLVs all the time and it works pretty well, the only problem being that sometimes .time is off by a little bit.
zeh
A: 

I ended using part of charlie-boy's suggestion adapting MediaStream.as to check every 100ms if the time property of the NetStream is the same (it's stuck in the end... or maybe just stuck but my specific situation will make that unlikely).

I added three properties to MediaStream:

private var last_time:Number = -1;
private var last_check:int  = 0;
private const check_delay:int = 100;

and changed the compareTime function like this:

    private function compareTime():void
    {
        if (isNaN(duration))
        {
            // when there is no metadata duration
            if (getTimer() - last_check > check_delay)
            {
                // enough time has passed since last check
                if (last_time==this.time)
                {
                    timer.stop();
                    timer.removeEventListener(TimerEvent.TIMER, onTimer);
                    dispatchEvent(new StreamEvent(StreamEvent.COMPLETE, null));
                }
                else
                {
                    last_check = getTimer();
                    last_time = this.time;
                }
            }
        }
        else if(!isNaN(duration) && this.time >= duration)
        {
            timer.removeEventListener(TimerEvent.TIMER, onTimer);
            dispatchEvent(new StreamEvent(StreamEvent.COMPLETE, null));
        }
    }

The worst case scenario is a 100ms "stuck frame" before loading the next clip. Not so bad for my specific need.

Thanks all for the input.

mga