我正在尝试同时播放多个视频流。但是,我无法同步这些视频以相同的速率播放。

- - 细节 - - - -

我有三个45秒的FLV格式视频,我使用flash.net.NetStream播放这些视频。我同时(通过使用for循环)调用这些netstream的netstream.play()。但是,即使所有视频文件都在我的本地计算机上,这些视频也不同步。

例如,当挂钟为第10秒时,第一个视频为第7秒,第二个视频为第10秒,最后一个视频为第5秒。

我认为它可能受到流传输时不同的抖动延迟的影响。但是,我仍然找不到解决此问题的方法。

最佳答案

这是我的研究结果。
码:

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
    i = 0时间= 5.251
    我= 1时间= 5.251
    i = 2时间= 5.538
    点击N 3
    i = 0时间= 37.721
    我= 1时间= 37.721
    我= 2时间= 37.721
    第一个和第二个流都可以,但第三个流总是晚287ms(这取决于onClick函数代码,以前的版本始终提供183ms的延迟)
  • 600-800秒后的:流时间(通常约为100毫秒)中存在不确定的增量,其次是两次单击:
    单击N 4
    i = 0时间= 756.44
    i = 1时间= 756.558
    i = 2时间= 756.558
    单击N 5
    i = 0时间= 4466.965
    我= 1时间= 4466.965
    i = 2时间= 4466.965

  • 和屏幕截图(第一部分是在第一次单击(在任何同步之前)之后拍摄的,第二部分是在单击N 4之后拍摄的):

    flv大小约为207mb btw

    UPD:我为视频添加了5个精灵,用于统计的文本字段和一个计时器(间隔为1000ms)来调用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);
                    }
                }
            }
        }
    

    每100秒大约有20个同步问题(跟踪,不是我能看到的问题),因为它使用了大量的系统资源,但是即使有寻找的痕迹,视频对象也可以流畅播放。
    这是图片:

    关于flash - 如何在ActionScript中同步多个视频流?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4052038/

    10-09 05:48
    查看更多