Search code examples
apache-flexflashactionscript-3videomxml

How to get current frame of currently playing video file?


So we have flv file, we play it with mx:vidodisplay for example. how to get on which stream frame we are currently on?


Solution

  • you can check the nearest keyframe to the current time in stream metadata
    upd
    when creating a stream you need to handle its' onMetaData call:

    private var metaInfo: Object;
    private function initStream():void{
         stream = new NetStream(conn);
         stream.bufferTime = 5;            
         stream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
         stream.client = new Object();
         stream.client.onMetaData = onMetaData;/*this is what you need*/
         video.attachNetStream(stream);
    }
    private function onMetaData(info:Object):void {
        metaInfo = info;
        var tmpstr:String = '';
        for(var s:String in info){
           var tstr:String = s + ' = ' + info[s] + '\n';
           tmpstr += tstr.indexOf('object') == -1 ? tstr : '';
           for(var a:String in info[s]){
               var ttstr:String = s + ':' + a + ' = ' + info[s][a] + '\n';
               tmpstr += ttstr.indexOf('object') == -1 ? ttstr : '';
                for(var c:String in info[s][a]){
                    var tttstr:String = s + ':' + a + ':' + c + ' = ' + info[s][a][c] + '\n';
                    tmpstr += tttstr.indexOf('object') == -1 ? tttstr : '';                     
                }
            }
        }
        trace(tmpstr);          
    }
    

    in this trace you'll see if the streams' metadata has items like:
    seekpoints:93:offset = 10342550
    seekpoints:93:time = 165.799

    or maybe:
    keyframes:times = 0,0.48,0.96,1.44,1.92,2.4,2.88,3.36,3.84,4.32,4.8,5.28,5.76,6.24
    keyframes:filepositions = 1063,95174,136998,176043,209542,239148,271062,302006,331724,363948,395039,427503,456317,483313

    it depends on encoder settings, if your metadata has any object of this kind (metadata['keyframes'], metadata['seekpoints'] etc) you can do the following:

    for (var i:int = 0; i < metaInfo['keyframes']['times'].length; i++) {
        if (stream.time < metaInfo['keyframes']['times'][i]) {
            var keyFrameNum: int = (metaInfo['keyframes']['times'][i] - stream.time < stream.time - metaInfo['keyframes']['times'][i - 1]) ? i : i - 1;
        }
    }