How to synchronize multiple video streams in ActionScript?

I am trying to play multiple video streams at the same time. However, I cannot sync these videos to play at the same speed.

---- details --------

I have three 45 second FLV format videos and I use flash.net.NetStream to play these videos. I call netstream.play () of these network streams at the same time (using for-loop). However, these videos are not synchronized, even all the video files are on my local machine.

For example, when the wall clock is at the 10th second, the first video is at the 7th second, the second video is at the 10th second, and the last video is at the 5th second.

I think this can be affected by various jitter delays in streaming. However, I still cannot find a way to solve this problem.

+3
source share
2 answers

here are my research results. the code:

package
{
    public class Main extends Sprite 
    {
        private var zeroBG:Sprite;
        private var oneBG:Sprite;
        private var twoBG:Sprite;
        private var arr:Array = new Array();
        private var oldSchoolMC:MovieClip;
        public function Main():void 
        {
            oldSchoolMC = new MovieClip();
            addChild(oldSchoolMC);
            oldSchoolMC.x = 400;
            oldSchoolMC.y = 350;
            oldSchoolMC.buttonMode = true;
            addFrames();
            //the string below is just a way to get about +15% CPU load (on Intel Dual-Core T4400), comment it out if you don't need it
            oldSchoolMC.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            oldSchoolMC.addEventListener(MouseEvent.CLICK, onClick);
            zeroBG = new Sprite();
            oneBG = new Sprite();
            twoBG = new Sprite();
            oneBG.x = 350;
            twoBG.x = 700;
            addChild(zeroBG);
            addChild(oneBG);
            addChild(twoBG);

            genVideoSampleOnDefaultClasses(zeroBG);
            genVideoSampleOnDefaultClasses(oneBG);
            genVideoSampleOnDefaultClasses(twoBG);
        }
        private function onClick(e:MouseEvent):void {
            var secs:int = 0;
            if ((arr[0] as NetStream).time != 0 && (arr[0] as NetStream).time != (arr[arr.length - 1] as NetStream).time) {
                secs = Math.ceil((arr[0] as NetStream).time);
            }
            for (var i:int = 0; i < arr.length; i++) {
                var ns:NetStream = arr[i] as NetStream;
                if(ns.time == 0){
                    ns.play('res/ghost_in_the_shell.flv');
                    continue;
                }else {
                    trace('i = ' + i + ' time = ' + ns.time);
                    if (secs != 0) {
                        ns.seek(secs);
                    }
                }               
            }
        }

        private function addFrames():void {
            for (var i:int = 0 ; i < 0xffffff ; i+=100000) {
                oldSchoolMC.addChild(genColRect(i));
                if (oldSchoolMC.numChildren > 0) {
                    oldSchoolMC.getChildAt(oldSchoolMC.numChildren - 1).scaleX = (250 - oldSchoolMC.numChildren) / 250;
                    oldSchoolMC.getChildAt(oldSchoolMC.numChildren - 1).scaleY = (250 - oldSchoolMC.numChildren) / 250;
                }
            }

        }

        private function onEnterFrame(e:Event):void {
            for (var i:int = 0 ; i < oldSchoolMC.numChildren ; i++) {
                oldSchoolMC.getChildAt(i).rotation += (oldSchoolMC.numChildren - i);
            }        
        }

        private function genColRect(col:int = 0xffffff):Shape {
            var spr:Shape = new Shape();
            spr.graphics.beginFill(col);
            spr.graphics.drawRect( -50, -50, 100, 100);
            spr.graphics.endFill();
            return spr;
        }        

        private function genVideoSampleOnDefaultClasses(spr:Sprite):void {
            var vid:Video = new Video();
            var nc:NetConnection = new NetConnection();
            nc.connect(null);
            var ns:NetStream = new NetStream(nc);
            ns.client = new Object();
            ns.client.onMetaData = function(info:Object):void { };
            vid.attachNetStream(ns);
            spr.addChild(vid);
            arr.push(ns);
        }

    }
}  

I can mention two synchronization issues:

  • :, , for 3- ((arr[0] as NetStream).play('res/ghost_in_the_shell.flv'); - ) ( , ) : ( ):
    N 2
    i = 0 = 5.251
    i = 1 = 5.251
    i = 2 = 5,538
    N 3
    i = 0 = 37.721
    i = 1 = 37.721
    i = 2 = 37.721
    , 287 ( onClick, 183 )
  • 600 - 800 : ( 100 ), :
    N 4
    i = 0 = 756.44
    i = 1 = 756.558
    i = 2 = 756.558
    N 5
    i = 0 = 4466.965
    i = 1 = 4466,965
    i = 2 = 4466,965


( ( ), N 4):

alt text

flv 207

UPD: 5 , ( 1000 ), onClick, :

    private function onClick(e:Event):void {
        tf.text = '';
        var secs:int = 0;
        if ((arr[0] as NetStream).time != 0 && (arr[0] as NetStream).time != (arr[arr.length - 1] as NetStream).time) {
            secs = Math.ceil((arr[0] as NetStream).time);
            trace(counter++ + ' : time = ' + secs);
        }
        for (var i:int = 0; i < arr.length; i++) {
            var ns:NetStream = arr[i] as NetStream;
            if(ns.time == 0){
                ns.play('res/ghost_in_the_shell.flv');
                if (i == arr.length - 1) {
                    streamTimer.start();
                }
                continue;
            }else {
                tf.appendText('# ' + i + ' [' + ns.time + ']\n');
                if (secs != 0) {
                    ns.seek(secs);
                }
            }               
        }
    }

20 100 (, , ), , , .
: alt text

+1

Oups.... , 2 ......

, , . NetStream ( , ...), .

function Preload() : void {
    aNet              = new NetConnection();
    aNet.connect(null);
    stream                = new NetStream( aNet );
    stream.client     = this;
    stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus, false, 0, true );
    stream.addEventListener(IOErrorEvent.IO_ERROR, errSnd, false, 0, true );
    stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError, false, 0, true );
    stream.play("your file");
}


// Here you wait for the load notification, and then pause the video.
private function onNetStatus( e : NetStatusEvent ) : void {
     switch( e.info.code ) {
      case "NetStream.Buffer.Full" :    
               if (bNotified) return;
               stream.pause();
               // Store that the file is loaded
               bNotified = true;
               // Dispatch an event
               dispatchEvent( new Event("VIDEO LOADED") ); 
       break;               
    }
}

private function errSnd(e: IOErrorEvent ) : void {
// error handling   

}

private function onAsyncError(e: AsyncErrorEvent ) : void {
    // Error handling
}
+1

Source: https://habr.com/ru/post/1772113/


All Articles