2011-09-09 42 views
0

我使用2个声道同时播放2个独立的外部加载的mp3文件。现在我有一个播放按钮绑定到一个功能,开始第一个MP3,然后是第二个。问题是 - 第二个mp3会在第一个几毫秒后开始。有没有一种方法可以确保这两款游戏在同一时间开始玩?动作 - 同步2声道?

function playMusic(evt:MouseEvent):void 
{ 

    channel = myMusic.play(songPosition); 
    channel2 = myMusic2.play(songPosition); 
    myTimer.start(); 
    btnPlay.mouseEnabled = false; 
} 

编辑:我发现了一个笨拙的解决方法,匹配2个音源的TIMER。它的工作原理,但现在我必须在一开始就打嗝,而我试图匹配:

function updateTime(evt:TimerEvent):void 
    { 
     lblSongTime.text = convertTime(channel.position); 
     if(channel.position!=channel2.position){ 
trace("out of sync")     
SoundMixer.stopAll() 
    channel = myMusic.play(); 
    channel2 = myMusic2.play(channel.position); 

     } 
    } 
+0

您是否尝试过使用'channel.position',而不是'songPosition'当您最初调用'myMusic2.play'? – jswolf19

+0

是的,昨天晚上我在尝试修复时试了一下。仍然开始不同步。我认为它必须是一个动作错误。任何帮助你可以给予不胜感激。 – user547794

+0

好的,我相信在一开始就摆脱了这个故障。在playMusic功能中,我将两个通道的音量设置为0.然后在同步校正之后,我将音量恢复。笨拙的,但工作,我想? – user547794

回答

2

如果你针对Flash Player的10+,那么你可以使用sampleData event和声音类的extract method要结合两个声音。

基本上,您需要制作Sound子类,通过将位置传递给要播放的两个声音中的每一个的extract方法来处理sampleData事件。然后,您将结合两个ByteArrays并将其插入事件的data成员中。

需要注意的主要问题是,一次只能给sampleData事件提供最多8K的数据(如果我没记错的话)。您也可能想要对这两个声音进行平均,或者至少在合并声音时减小音量。

自从我写了actionscript之后已经有一段时间了,所以我花了一点时间为你写一些代码,但是如果你仍然需要帮助,请告诉我,我会尝试给你更多的信息或一些代码。

编辑

这里有一个最小的类,它会做你想要什么。您应该添加错误检查,您可能需要添加东西来处理声音转换(例如音量调整),因为使用示例数据事件可能会忽略您在播放时应用的声音转换(我不记得,但它不应该太你很难找出答案^ _ ^)...

import flash.events.SampleDataEvent; 
import flash.media.Sound; 
import flash.utils.ByteArray; 

public class DualSound extends Sound { 
    private var sa:Sound; 
    private var sb:Sound; 

    public function DualSound(a:Sound, b:Sound) { 
     super(); 

     sa = a; 
     sb = b; 

     addEventListener(SampleDataEvent.SAMPLE_DATA, handleSampleData); 
    } 

    private function handleSampleData(e:SampleDataEvent):void { 
     var ba:ByteArray, bb:ByteArray; 

     ba = new ByteArray(); 
     bb = new ByteArray(); 

     sa.extract(ba, 8 << 10, e.position); 
     sb.extract(bb, 8 << 10, e.position); 
     ba.position = 0; 
     bb.position = 0; 

     while(ba.bytesAvailable > 0 && bb.bytesAvailable > 0) { 
      e.data.writeFloat((ba.readFloat() + bb.readFloat())/2); 
     } 
     if(ba.bytesAvailable > 0) { 
      e.data.writeBytes(ba, ba.position, ba.bytesAvailable); 
     } else if(bb.bytesAvailable > 0) { 
      e.data.writeBytes(bb, bb.position, bb.bytesAvailable); 
     } 
    } 
} 
+0

我不完全清楚你在说什么。我确实发现了一个非常笨拙的工作 - 基本上它会检查audio2的TIMER是否与audio1的TIMER匹配。问题是现在,它跳过用于第二击中发挥后而它试图匹配: \t功能注册(EVT:TimerEvent):无效 \t { \t \t lblSongTime.text = convertTime(channel.position); \t \t \t 如果\t { 迹( “不同步”) SoundMixer.stopAll() \t信道= myMusic.play()(channel.position = channel2.position!); \t channel2 = myMusic2.play(channel。位置); \t \t} \t} – user547794

+0

@user,我已经添加了一个类的代码,如果您对解决方法不满意,它会根据需要进行操作。 – jswolf19