Как синхронизировать несколько видеопотоков в ActionScript? - PullRequest
3 голосов
/ 29 октября 2010

Я пытаюсь воспроизвести несколько видеопотоков одновременно.Однако я не могу синхронизировать эти видео для воспроизведения с той же скоростью.

---- подробности --------

У меня есть три 45-секундных видео в формате FLV иЯ использую flash.net.NetStream для воспроизведения этих видео.Я вызываю netstream.play () этих netstream одновременно (используя цикл for).Однако эти видео не синхронизированы, даже если все видеофайлы находятся на моем локальном компьютере.

Например, когда настенные часы находятся на 10-й секунде, первое видео находится на 7-й секунде, второе видео -на 10-й секунде, а последнее видео на 5-й секунде.

Я думаю, что на него могут влиять различные задержки дрожания при потоковой передаче.Тем не менее, я до сих пор не могу найти способ решить эту проблему.

Ответы [ 2 ]

1 голос
/ 05 апреля 2013

Упс .... не видел, это было 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 голос
/ 29 октября 2010

вот мои результаты исследований. код:

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);
        }

    }
}  

Я могу упомянуть две проблемы синхронизации:

  • при запуске: независимо от того, использую ли я цикл for или просто жестко кодирую 3 строки ((arr[0] as NetStream).play('res/ghost_in_the_shell.flv'); - таким образом), вывод при втором щелчке (после запуска воспроизведения) выглядит следующим образом ( следы от второго и третьего кликов):
    нажмите N 2
    я = 0 раз = 5,251
    я = 1 раз = 5,251
    я = 2 раза = 5,538
    нажмите N 3
    я = 0 раз = 37,721
    я = 1 раз = 37,721
    я = 2 раза = 37,721
    первый и второй потоки в порядке, но третий всегда опаздывает на 287 мс (это зависит от кода функции onClick, предыдущая версия всегда давала задержку в 183 мс)
  • через 600 - 800 секунд: имеется неопределенная разница во времени потоков (обычно около 100 мс), следы от двух следующих кликов:
    нажмите N 4
    я = 0 раз = 756,44
    я = 1 раз = 756,558
    я = 2 раза = 756,558
    нажмите N 5
    я = 0 раз = 4466,965
    я = 1 раз = 4466,965
    я = 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

...