Flash 循环声音闪光as3的首选方法
我在flash AS3中循环声音时遇到了一些问题,因为当我告诉声音循环时,音频的结尾/开头会有一点延迟 音频剪辑正确,在车库乐队上播放时不会出现间隙 我知道flash中的声音一般都有问题,编码有缺陷,声音完成事件不准确(Adobe应对这些问题的处理感到尴尬) 我尝试在Sound类的play方法中使用内置循环参数,并对Sound_COMPLETE事件做出反应,但两者都会导致延迟Flash 循环声音闪光as3的首选方法,flash,actionscript-3,audio,Flash,Actionscript 3,Audio,我在flash AS3中循环声音时遇到了一些问题,因为当我告诉声音循环时,音频的结尾/开头会有一点延迟 音频剪辑正确,在车库乐队上播放时不会出现间隙 我知道flash中的声音一般都有问题,编码有缺陷,声音完成事件不准确(Adobe应对这些问题的处理感到尴尬) 我尝试在Sound类的play方法中使用内置循环参数,并对Sound_COMPLETE事件做出反应,但两者都会导致延迟 但是有没有人想出了一种无明显间隙的声音循环技术?下面是我是如何做到的,没有明显的延迟。主应用程序: package {
但是有没有人想出了一种无明显间隙的声音循环技术?下面是我是如何做到的,没有明显的延迟。主应用程序:
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文件在开始/结束时没有延迟,但我建议使用打开它,并确保没有延迟。如果您可以使用Flash Player 10,最可靠的方法是使用新的SampleDataEvent.SAMPLE\u数据事件 具体地说,您要做的是首先实例化所需的声音,然后使用新的提取方法将声音转换为ByteArray中编码的原始PCM数据。然后,您可以创建一个新的声音对象,并设置为侦听它的SampleDataEvent.SAMPLE_数据事件。调用该事件时,您将从ByteArray中推送2-8k(较低的推送量会减少延迟,但会增加声音伪影的可能性)。您只需确保在运行ByteArray的末尾时,您只需返回到开头即可
此方法可确保完全无间隙播放。根据,必须将音乐循环作为wav导入,并将Flash IDE本身压缩为mp3。让Flash使用导入的mp3数据意味着它不知道如何正确地循环。由于格式的工作方式,mp3的无间隙循环并非微不足道。简化一点;声音适合多个帧,不能任意选择这个数字,而是需要一些填充(带静音)。Mp3无法存储添加了多少填充,因此一旦文件编码,这些信息就会丢失 FlashIDE通过嵌入元数据来解决这个问题,您也可以这样做。您只需要知道编码器增加了多少延迟 安德烈·米歇尔 我使用这个很棒的工具: 您给它一个WAV文件,它返回一个MP3文件,可以使用
声音的标准播放方法完美地(无间隙地)播放该文件-例如:
var manyLoops:int = 1000*1000; // a Million is a lot :)
mySound.play(0, manyLoops);
您还可以将输出的MP3文件重新转换为WAV(例如使用AudioCity)——然后您就有了一个无间隙的WAV(在FLA文件中可以很好地工作)
希望它有帮助我想创建一个不依赖完整事件的循环音频库。我决定创造我自己的。看看原件。挖掘正在进行的工作,并在字节级别完成工作(没有循环计时器或任何东西)。它的工作原理是接收带有起始和结束循环点的声音。然后根据以秒为单位提供的时间,将循环样本克隆一系列次。它应该直接使用。这是中Main.as类的代码
“示例”文件夹中的“循环”文件:
请在此处查看源文件:
这是一个很酷的功能,它使一些很棒的东西(如hobnox)成为可能,但遗憾的是,为了流畅地播放声音循环,必须采用低级字节操作。播放器和声音API中的音频支持非常糟糕。这太糟糕了,但这些问题都存在于这样一个事实上:Flash player声音引擎非常旧,只需要更新,应该在播放器11中提供。当然,这比调用play():)更复杂,但听起来像是一个确定性的解决方案。我会试试Brandon,然后再告诉你。老兄,这让我很生气,你不得不求助于这个!这样一个荒谬的CPU和内存密集型的事情只是为了让音乐无缝循环@Branden Hall,我想应用你的方法来循环大量的声音片段(彼此并行运行),如果我能看到一个算法如何实现的例子,我会很高兴。示例代码,伪代码/算法,任何东西都可以。嘿,Mercer,这基本上就是我一直在使用的方法,希望它不会在每次声音完成时重新定位音频。我会试一试,看看结果如何。谢谢Mercer,我刚刚试过这个,这个差距对于循环音乐来说太明显了。谢谢分享你的代码,tho!哦,事实上,倒过来。也许这种方法是有效的。我使用的声音在开始和结束时有微小的间隙。谢啦,布莱恩,我知道你已经接受了布兰登的回答,但你能告诉我默瑟的解决方案是否有效吗?你试过了吗?如果我能帮助的话,我不想使用示例数据事件…嗯,我可以回答我的问题:不。在event.SOUND\u COMPLETE事件处理程序中调用play并不能消除间隙,至少在os x、FP10上是这样。事实上,event.SOUND\u COMPLETE事件方法实际上可以工作。我使用的文件在开始和结束时都有很小的间隙。@aaaidan根据我的经验,@Mercer提出的解决方案仍然有很好的机会出现明显的延迟。似乎@grapefrukt和yourseld已经发现了一些重要的问题,这些问题与帮助循环的额外元数据有关
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.
}
}
}