Spela upp ljud

Flash Player 9 och senare, Adobe AIR 1.0 och senare

Att spela upp ett inläst ljud kan vara så enkelt som att anropa metoden Sound.play() för ett Sound-objekt, enligt nedanstående:

var snd:Sound = new Sound(new URLRequest("smallSound.mp3")); 
snd.play();

När ljud spelas upp med ActionScript 3.0 kan du utföra följande:

  • Spela upp ett ljud från en viss startposition

  • Pausa ett ljud och återuppta uppspelningen från samma position senare

  • Veta exakt när en ljuduppspelning slutar

  • Spåra uppspelningsförloppet för ett ljud.

  • Ändra volym och panorering medan ett ljud spelas upp

Använd klasserna SoundChannel, SoundMixer och SoundTransform när du vill utföra de här åtgärderna under uppspelning.

Klassen SoundChannel styr uppspelningen av ett enstaka ljud. Du kan tänka på egenskapen SoundChannel.position som ett spelhuvud som indikerar den aktuella ljuddatapositionen som just nu spelas upp.

När programmet anropar en Sound.play()-metod skapas en ny instans av klassen SoundChannel för styrning av uppspelningen.

Programmet kan spela upp ett ljud från en specifik startposition genom att överföra positionen, uttryckt i millisekunder, som startTime-parameter för Sound.play()-metoden. Det kan också specificera ett fast antal gånger som ljudet ska repeteras i snabb följd genom att överföra ett numeriskt värde i parametern loops för Sound.play()-metoden.

När Sound.play()-metoden anropas med både en startTime-parameter och en loops-parameter, spelas ljudet upp upprepade gånger från samma referenspunkt varje gång enligt exemplet i följande kod:

var snd:Sound = new Sound(new URLRequest("repeatingSound.mp3")); 
snd.play(1000, 3);

I det här exemplet spelas ljudet upp från en punkt en sekund efter att ljudet har startats och tre gånger i följd.

Pausa och fortsätta ljuduppspelning

Om långa ljud spelas upp i programmet, som låtar eller poddsändningar, vill du antagligen att användarna ska kunna pausa och återuppta uppspelningen av dessa ljud. Ett ljud kan egentligen inte pausas under uppspelning i ActionScript; det kan endast stoppas. Men ett ljud kan spelas upp med start från en viss punkt. Du kan spela in ljudpositionen när den stoppas och sedan spela upp ljudet med start från den positionen senare.

Vi antar att koden läser in och spelar en ljudfil liknande den här:

var snd:Sound = new Sound(new URLRequest("bigSound.mp3")); 
var channel:SoundChannel = snd.play();

När ljudet spelas upp indikerar SoundChannel.position-egenskapen den position i ljudfilen som spelas upp just nu. Programmet kan lagra positionsvärdet innan ljudet stoppas:

var pausePosition:int = channel.position; 
channel.stop();

För att återuppta uppspelningen av ljudet överför du det tidigare lagrade positionsvärdet för att återstarta ljudet från samma position det stoppade på förut.

channel = snd.play(pausePosition);

Övervaka uppspelning

Programmet behöver en indikation om när en ljuduppspelning stoppas så det kan starta uppspelningen av ett annat ljud eller rensa några resurser som använts under den tidigare uppspelningen. Klassen SoundChannel skickar en Event.SOUND_COMPLETE-händelse när dess ljuduppspelning är slut. Programmet kan lyssna efter händelsen och utföra lämplig åtgärd enligt exemplet nedan:

import flash.events.Event; 
import flash.media.Sound; 
import flash.net.URLRequest; 
 
var snd:Sound = new Sound(); 
var req:URLRequest = new URLRequest("smallSound.mp3"); 
snd.load(req); 
 
var channel:SoundChannel = snd.play(); 
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 
 
public function onPlaybackComplete(event:Event) 
{ 
    trace("The sound has finished playing."); 
}

Klassen SoundChannel skickar inte progress-händelser under uppspelning. För rapport om uppspelningsförloppet kan du ange att programmet ska ha en egen timingmekanism och spåra positionen för spelhuvudet.

För beräkning av hur stor procentandel av ljudet som har spelats upp kan du dividera värdet för SoundChannel.position-egenskapen med längden för ljuddata som spelas upp:

var playbackPercent:uint = 100 * (channel.position / snd.length);

Men den här koden rapporterar endast rätt procentsats för uppspelning om ljuddata var fullständigt inläst innan uppspelningen började. Egenskapen Sound.length visar storleken på ljuddata som för närvarande är inläst, inte den slutliga storleken för hela ljudfilen. Om du vill spåra uppspelningsförloppet för ett direktuppspelat ljud som fortfarande läses in, kan programmet beräkna den slutliga storleken för hela ljudfilen och använda det värdet vid beräkningarna. Du kan beräkna den slutliga längden för ljuddata med hjälp av egenskaperna bytesLoaded och bytesTotal för Sound-objektet enligt följande:

var estimatedLength:int =  
    Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal)); 
var playbackPercent:uint = 100 * (channel.position / estimatedLength);

I följande kod läses en större ljudfil in och Event.ENTER_FRAME-händelsen används som timingmekanism för att visa uppspelningsförloppet. Periodvis rapporteras hur stor procent som spelats upp, vilket beräknas som nuvarande positionsvärde dividerat med den totala längden av ljuddata:

import flash.events.Event; 
import flash.media.Sound; 
import flash.net.URLRequest; 
 
var snd:Sound = new Sound(); 
var req:URLRequest = new  
    URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3"); 
snd.load(req); 
 
var channel:SoundChannel; 
channel = snd.play(); 
addEventListener(Event.ENTER_FRAME, onEnterFrame); 
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 
 
function onEnterFrame(event:Event):void 
{ 
    var estimatedLength:int =  
        Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal)); 
    var playbackPercent:uint =  
        Math.round(100 * (channel.position / estimatedLength)); 
    trace("Sound playback is " + playbackPercent + "% complete."); 
} 
 
function onPlaybackComplete(event:Event) 
{ 
    trace("The sound has finished playing."); 
    removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
}

När ljuddata börjar läsas in anropar koden metoden snd.play() och lagrar det slutliga SoundChannel-objektet i variabeln channel. Sedan läggs en händelseavlyssnare till i huvudprogrammet för Event.ENTER_FRAME-händelsen och en annan händelseavlyssnare till SoundChannel-objektet för Event.SOUND_COMPLETE-händelsen som inträffar när uppspelningen är slutförd.

Varje gång programmet kommer till en ny bildruta i animeringen anropas onEnterFrame()-metoden. Metoden onEnterFrame() beräknar den totala längden för ljudfilen baserat på den datamängd som redan har lästs in och sedan beräknar den och visar hur stor procent som spelats upp.

När hela ljudet har spelats upp, körs onPlaybackComplete()-metoden som tar bort händelseavlyssnaren från Event.ENTER_FRAME-händelsen så att den inte försöker visa förloppsuppdateringar när uppspelningen är klar.

Händelsen Event.ENTER_FRAME kan skickas många gånger per sekund. I vissa fall vill du inte visa uppspelningsförloppet så ofta. I dessa fall kan du ange en egen timingmekanism med klassen flash.util.Timer; se Arbeta med datum och tidpunkter.

Stoppa direktuppspelade ljud

Det finns en egenhet i uppspelningsprocessen för ljud som direktuppspelas, alltså för ljud som fortfarande läses in medan de spelas upp. När programmet anropar metoden SoundChannel.stop() i en SoundChannel-instans som spelar upp ett direktuppspelat ljud, stoppas ljuduppspelningen först i en bildruta och sedan, i nästa bildruta, startas det om från början av ljudet. Det här sker för att ljudinläsningsförloppet fortfarande pågår. Om du vill stoppa både inläsningen och uppspelningen av ett direktuppspelat ljud anropar du Sound.close()-metoden.