Воспроизведение звуков

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Чтобы воспроизвести загруженный звук, достаточно вызвать метод Sound.play() для объекта Sound, как показано ниже.

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

Когда звук воспроизводится с помощью ActionScript 3.0, можно выполнять следующие операции:

  • воспроизводить звук начиная с определенного места;

  • приостановить звук и позднее возобновить воспроизведение с того же места;

  • узнать точное время завершения воспроизведения звука;

  • отслеживать прогресс воспроизведения звука;

  • изменить громкость или панорамирование в процессе воспроизведения звука.

Для выполнения этих операций в ходе воспроизведения можно использовать классы SoundChannel, SoundMixer и SoundTransform.

Класс SoundChannel управляет воспроизведением одного звука. Свойство SoundChannel.position можно представить как точку воспроизведения, которая указывает текущую позицию в воспроизводимых аудиоданных.

Когда приложение вызывает метод Sound.play() , создается новый экземпляр класса SoundChannel для управления воспроизведением.

Приложение может воспроизводить звук, начиная с определенного места. Для этого нужно указать это место в миллисекундах в параметре startTime метода Sound.play() . Также можно указать фиксированное число повторов звука в непрерывной последовательности, передав числовое значение в параметре loops метода Sound.play() .

Когда метод Sound.play() вызывается с использованием обоих параметров startTime и loops , звук воспроизводится несколько раз, начиная с одного и того же места, как в следующем коде.

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

В этом примере звук воспроизводится с точки, которая находится через одну секунду после начала звука, и повторяется три раза подряд.

Приостановка и возобновление звука

Если приложение воспроизводит звуки большого размера, например песни или подкасты, вероятно, следует предоставить пользователю возможность приостанавливать и возобновлять воспроизведение таких аудиофайлов. В ActionScript воспроизводимый звук нельзя приостановить в буквальном смысле, его можно только остановить полностью. Однако звук можно воспроизводить с любой точки. Можно записать позицию звука в момент остановки, а затем продолжить его воспроизведение, начиная с этого же места.

Например, код загружает и воспроизводит аудиофайл, как показано ниже.

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

Во время воспроизведения звука свойство SoundChannel.position указывает точку файла, которая воспроизводится в данный момент. Приложение может сохранить значение позиции, в которой звук находился перед остановкой, как показано ниже.

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

Чтобы возобновить звук, передайте сохраненное ранее значение позиции, чтобы начать воспроизведение с того же места, где оно было остановлено.

channel = snd.play(pausePosition);

Отслеживание воспроизведения

Возможно, приложению потребуется информация о том, когда заканчивается воспроизведение одного звука, чтобы запустить другой или удалить ресурсы, использованные при предыдущем воспроизведении. Класс SoundChannel отправляет событие Event.SOUND_COMPLETE , когда заканчивается воспроизведение его звука. Приложение может прослушивать это событие и, получив его, предпринять соответствующее действие, как показано ниже.

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

Класс SoundChannel не отправляет события progress во время воспроизведения. Чтобы регистрировать прогресс воспроизведения, приложение может создать собственный механизм контроля времени и отслеживать позицию точки воспроизведения.

Чтобы вычислить, какой процент звука уже воспроизведен, можно разделить значение свойства SoundChannel.position на продолжительность аудиоданных.

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

Однако этот код сообщает точные проценты воспроизведения, только если оно началось после полной загрузки аудиоданных. Свойство Sound.length показывает размер загруженных на данный момент аудиоданных, а не конечный размер всего аудиофайла. Чтобы отслеживать прогресс воспроизведения потокового звука, загрузка которого еще не завершилась, приложение должно подсчитать конечный размер полного аудиофайла и использовать это значение в вычислениях. Подсчитать конечную продолжительность аудиоданных можно с помощью свойств bytesLoaded и bytesTotal объекта Sound, как показано ниже.

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

Следующий код загружает более объемный звуковой файл и использует событие Event.ENTER_FRAME в качестве механизма определения времени для отображения прогресса воспроизведения. Код периодически сообщает процент воспроизведенного звука, то есть текущее значение позиции, деленное на общую продолжительность аудиоданных.

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

После начала загрузки аудиоданных код вызывает метод snd.play() и сохраняет созданный в результате этого объект SoundChannel в переменной channel . Затем для главного приложения добавляется прослушиватель события Event.ENTER_FRAME , а для объекта SoundChannel — прослушиватель события Event.SOUND_COMPLETE , которое отправляется после завершения воспроизведения.

Каждый раз, когда приложение достигает следующего кадра анимации, вызывается метод onEnterFrame() . Метод onEnterFrame() рассчитывает общую продолжительность аудиофайла на основе уже загруженного объема данных, а затем вычисляет и отображает текущий процент воспроизведения.

По завершении воспроизведения всего звука выполняется метод onPlaybackComplete() , который удаляет прослушиватель события Event.ENTER_FRAME , чтобы предотвратить попытки отображения обновлений прогресса после окончания воспроизведения.

Событие Event.ENTER_FRAME может отправляться много раз в секунду. Иногда отображать прогресс воспроизведения с такой частотой не требуется. В таких случаях приложение может создать собственный механизм определения времени с помощью класса flash.util.Timer. Сведения см. в разделе Работа с датами и временем .

Остановка потоковых звуков

Процесс воспроизведения потоковых звуков имеет одну особенность: воспроизведение звука начинается до завершения его загрузки. Когда приложение вызывает метод SoundChannel.stop() для экземпляра SoundChannel, который воспроизводит потоковый звук, воспроизведение останавливается для одного кадра, а при переходе к следующему кадру оно возобнавляется с начала звука. Это происходит потому, что процесс загрузки звука еще не завершен. Чтобы одновременно остановить и загрузку и воспроизведение потокового звука, нужно вызвать метод Sound.close() .