【问题标题】:actionscript - syncronizing 2 sound channels?actionscript - 同步 2 个声道?
【发布时间】:2011-09-09 02:09:15
【问题描述】:

我正在使用 2 个声道同时播放 2 个单独的、外部加载的 mp3 文件。现在我将播放按钮绑定到启动第一个 mp3 的功能,然后是第二个。问题是 - 第二个 mp3 在第一个之后几毫秒开始。有没有办法可以确保这两个同时开始播放?

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

        }
    }

【问题讨论】:

  • 您是否尝试在最初调用myMusic2.play 时使用channel.position 而不是songPosition
  • 是的,我昨晚在寻找修复程序时尝试了这一点。仍然开始不同步。我想它一定是一个动作脚本错误。非常感谢您提供的任何帮助。
  • 好吧,我相信我一开始就摆脱了小故障。在 playMusic 功能中,我将两个通道的音量设置为 0。然后在同步校正后将音量调高。笨拙,但我认为有效?

标签: flash actionscript-3 actionscript


【解决方案1】:

如果您的目标是 Flash Player 10+,那么您可以使用声音类的 sampleData eventextract method 来组合这两种声音。

基本上,您需要创建一个处理sampleData 事件的Sound 子类,方法是将位置传递给您要播放的两种声音中的每一种的extract 方法。然后,您将合并这两个 ByteArrays 并将其插入到事件的 data 成员中。

需要注意的主要事情是,您一次最多只能向sampleData 事件提供 8k 数据(如果我没记错的话)。您可能还希望平均两种声音,或者至少在组合声音时降低音量。

我已经有一段时间没有写动作脚本了,所以我需要一些时间来为你写一些代码,但如果你仍然需要帮助,请告诉我,我会尽力给你更多信息或一些代码。

编辑

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

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

【讨论】:

  • 我不太清楚你在说什么。我确实发现了一个非常笨拙的工作 - 基本上它检查audio2的TIMER是否与audio1的TIMER匹配。现在的问题是它在尝试匹配时在点击播放后跳过一秒钟: function updateTime(evt:TimerEvent):void { lblSongTime.text = convertTime(channel.position); if(channel.position!=channel2.position){ trace("不同步") SoundMixer.stopAll() channel = myMusic.play(); channel2 = myMusic2.play(channel.position); } }
  • @user,我添加了一个类的代码,如果你对你的解决方法不满意,它会做你想做的事。
猜你喜欢
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多