我遇到了在flash AS3中循环声音的问题,因为当我告诉声音循环时,我会在音频结束/开始时稍微延迟。
音频被正确剪辑,并且在车库乐队中无间隙地播放。
我知道闪存中存在声音问题,编码错误以及SOUND_COMPLETE事件的不准确性(Adobe应该对这些问题的处理感到尴尬)
我试图在Sound类的play方法中使用内置循环参数,并对SOUND_COMPLETE事件做出反应,但都会导致延迟。
但有没有人想出一种没有任何明显差距的声音循环技术?
答案 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