用于循环声音闪烁as3的首选方法

时间:2009-08-04 13:07:57

标签: flash actionscript-3 audio

我遇到了在flash AS3中循环声音的问题,因为当我告诉声音循环时,我会在音频结束/开始时稍微延迟。

音频被正确剪辑,并且在车库乐队中无间隙地播放。

我知道闪存中存在声音问题,编码错误以及SOUND_COMPLETE事件的不准确性(Adobe应该对这些问题的处理感到尴尬)

我试图在Sound类的play方法中使用内置循环参数,并对SOUND_COMPLETE事件做出反应,但都会导致延迟。

但有没有人想出一种没有任何明显差距的声音循环技术?

6 个答案:

答案 0 :(得分:7)

如果可以使用Flash Player 10,最可靠的方法是使用新的SampleDataEvent.SAMPLE_DATA事件。

具体来说,您要做的是首先实例化您想要的声音,然后使用新的提取方法将声音转换为ByteArray中编码的原始PCM数据。然后,您可以创建一个新的Sound对象,并设置为侦听它的SampleDataEvent.SAMPLE_DATA事件。当调用该事件时,您将从ByteArray推送2-8k(较低的数量减少延迟,但会增加可听到的伪像的可能性)。你只需要确保当你运行ByteArray的末尾时,你只需循环回到开头。

此方法可确保您完全无间隙播放。

答案 1 :(得分:5)

由于格式的工作方式,mp3的无缝循环并非易事。简化一点;声音适合多个帧,这个数字不能任意选择,而是需要一些填充(带静音)。 Mp3无法存储添加的填充量,因此一旦文件被编码,此信息就会丢失。

Flash IDE通过嵌入这些元数据来解决这个问题,你也可以。您只需要知道编码器添加了多少延迟。

Andre Michelle explains this way better than I can on his blog

答案 2 :(得分:3)

根据this guy,您必须将音乐循环导入为wav,并让Flash IDE本身压缩为mp3。让Flash使用导入的mp3数据意味着它不知道如何正确循环它。

答案 3 :(得分:1)

这是id如何做到的,没有明显的延迟。主要应用:

package {

import flash.display.MovieClip; 
import flash.events.*;
import flash.utils.*;

public class MainApp extends MovieClip {
  private var player:Player;
  ..........

  public function MainApp() {
      .......
      player = new Player();
      player.addEventListener(Player.EVENT_SOUND_COMPLETED, handleSoundCompleted);
      ......
  }

  private function handleSoundCompleted(event:Event):void {
      player.setPosition(0);
      player.play();
  }

  .................

玩家类:

package {

import flash.events.*;
import flash.media.*;
import flash.net.*;

public class Player extends EventDispatcher {

    private var sound:Sound;
    private var channel:SoundChannel;
    private var position:Number;

    static const SOUND_VOLUME:Number = 0.75;
    static const EVENT_SOUND_COMPLETED:String = "SOUND_COMPLETED";

    public function Player() {

        // init
        sound = new ThemeSong();
        position = 0;

        // listeners
        sound.addEventListener(IOErrorEvent.IO_ERROR, function(event:Event){trace(event)});

        trace("Player initialized...");
    }

    public function play():void {
        channel = sound.play(position);
        channel.soundTransform = new SoundTransform(SOUND_VOLUME);
        channel.addEventListener(Event.SOUND_COMPLETE, function(event:Event){dispatchEvent(new Event(EVENT_SOUND_COMPLETED));});
        trace("Player playing..");
    }

    public function pause():void {
        if (channel != null) {
            channel.stop();
            position = channel.position;
        }
        trace("Player paused..");
    }

    public function setPosition(pos:Number):void {
        position = pos;
    }

    public function getPosition():Number {
        if (channel == null) {
            return 0;
        } else {
            return channel.position;
        }
    }
}
}

你确实说mp3文件在开始/结束时没有延迟,但我建议用audacity打开它,并确保没有延迟。

答案 4 :(得分:1)

我使用这个伟大的工具:     http://www.compuphase.com/mp3/mp3loop.zip

你给它一个WAV文件,它会返回一个MP3文件,可以使用Sound的标准play方法完美地(无间隙!)播放 - 例如:

var manyLoops:int = 1000*1000; // a Million is a lot :)
mySound.play(0, manyLoops); 

你也可以把输出MP3文件重新转换为WAV(例如使用AudioCity) - 然后你就可以使用无间隙WAV(可以在你的FLA文件中运行得很好)

希望有所帮助

答案 5 :(得分:0)

我想创建一个用于循环音频的库,它不依赖于COMPLETE事件。我决定创建自己的standingwave3 addons library。查看原始standingwave3 project by MaxL0rd。挖掘正在进行的工作并完成工作,在字节级别上完成(无循环定时器或任何东西)。它通过带有开始和结束循环点的声音来工作。然后它根据秒提供的时间克隆循环样本一堆。它应该是直接使用。这是Main.as类的代码 "循环"文件在"示例"文件夹:

package
{

    // Imports.
    import com.greensock.events.LoaderEvent;
    import com.greensock.loading.LoaderMax;
    import com.greensock.loading.MP3Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import com.greensock.TweenMax;
    import com.SW3.gadget.LoopGadget;
    import flash.media.Sound;


    // Class.
    public class Main extends Sprite
    {

        // Vars.
        private var loader:LoaderMax;// Using LoaderMax for ease of use.


        // Constructor.
        public function Main()
        {

            trace("Main");

            loader = new LoaderMax( { name:"audio", onComplete:onSoundsLoaded } );
            loader.append( new MP3Loader( "assets/Beat.mp3", { autoPlay:false } ) );
            loader.append( new MP3Loader( "assets/Clap.mp3", { autoPlay:false } ) );
            loader.append( new MP3Loader( "assets/Boom.mp3", { autoPlay:false } ) );
            loader.load();

        }


        private function onSoundsLoaded(e:LoaderEvent):void
        {

            trace("onSoundsLoaded");
            var looping:LoopGadget = new LoopGadget;
            looping.addLoopSound( "Beat", e.currentTarget.content[ 0 ] as Sound, 0, 10 );
            looping.addLoopSound( "Clap", e.currentTarget.content[ 1 ] as Sound, 0, 10 );
            //looping.addLoopSound( "Boom", e.currentTarget.content[ 2 ] as Sound, 0, 10 ); // Commented out to test possible error.

            looping.playLoop( "Beat" );// Play the "Beat" loop.
            looping.playLoop( "Clap" );// Play the "Clap" loop.
            looping.stopLoop( "Beat" );// Stop the "Beat" loop.
            looping.playLoop( "Beat" );// Play the "Beat" loop.
            looping.playLoop( "Beat" );// Play the "Beat" loop again to test if it would error out..

            looping.stopAllLoops();// Stop all the loops.
            looping.playLoops( [ "Beat", "Clap", "Boom" ] );// Play all the loops. Test to see if "Boom" will error out.

        }

    }

}

在这里查看源文件: https://github.com/charlesclements/standingwave3-addons