我正在尝试同时播放多个视频流。但是,我无法以同样的速度同步这些视频。
----详情--------
我有三个45秒的FLV格式视频,我使用flash.net.NetStream播放这些视频。我同时调用这些netstream的netstream.play()(通过使用for循环)。但是,即使所有视频文件都在我的本地计算机上,这些视频也是不同步的。
例如,当挂钟为第10秒时,第一个视频为第7秒,第二个视频为第10秒,最后一个视频为第5秒。
我认为流式传输时可能会受到不同抖动延迟的影响。但是,我仍然找不到解决这个问题的方法。
答案 0 :(得分:1)
这是我的研究结果。 代码:
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 4 之后拍摄的):
flv大小约为207mb btw
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);
}
}
}
}
它每100秒有大约20个同步问题(跟踪,而不是我能看到的问题),因为它使用了大量的系统资源,但即使有关于搜索的痕迹,视频对象也能够流畅地播放。
这是图片:
答案 1 :(得分: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
}