Search code examples
actionscript-3flashbufferingnetstream

NetStream: dual threshold buffering, and seeking beyond buffer


This was a helpful article about dual threshold buffering. It explains that you can listen for the NetStream.Buffer.Full and NetStream.Buffer.Empty events on a NetStream and adjust the NetStream's buffer time accordingly to make the best use of available bandwidth and also get fast video start times. I've encountered a problem though. When I seek past the buffered section of video in my NetStream, the buffer is once again empty, but I don't get a NetStream.Buffer.Empty event. The NetStream's buffer time is still set to my expanded buffer time so I lose the advantage of a fast start time. How do you implement this strategy so that it works properly in this case? How do you tell that the buffer is empty again or that you have seeked past the available buffer?

Edit: I should probably mention I am using in-buffer seeking (Smart Seeking). I think this wouldn't be a problem if I wasn't, because flash flushes the buffer on every seek without this feature enabled.


Solution

  • The solution for me was to just reset the buffer time on every seek. You'll still get the NetStream.Buffer.Full event, and it'll fire immediately if you happen to seek to a location where the buffer is already larger your minimum buffer, so your handler for NetStream.Buffer.Full will just immediately set the buffer time back to your expanded buffer time. Here's an example:

    var videoStream:NetStream = new NetStream(nc);
    
    videoStream.addEventListener(NetStatusEvent.NET_STATUS, function (event:NetStatusEvent):void {
        switch(event.info.code) {
            case "NetStream.Buffer.Full":
                // this will keep the buffer filling continuously while there is bandwidth
                videoStream.bufferTime = Settings.maxBuffer;
                State.buffering = false;
                break;
            case "NetStream.Buffer.Empty":
                // if we run out of buffer we'll reset the buffer time to the min
                videoStream.bufferTime = Settings.minBuffer;
                State.buffering = true;
                break;
        }
    }
    
    _view.addEventListener(SeekEvent.SEEK, function (event:SeekEvent):void {
        State.buffering = true;
        videoStream.bufferTime = Settings.minBuffer;
        videoStream.seek(event.seek * (_duration || 0));
    });