All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.feathers.media.SoundPlayer.as Maven / Gradle / Ivy

/*
Feathers
Copyright 2012-2015 Bowler Hat LLC. All Rights Reserved.

This program is free software. You can redistribute and/or modify it in
accordance with the terms of the accompanying license agreement.
*/
package feathers.media
{
	import feathers.events.MediaPlayerEventType;
	import feathers.skins.IStyleProvider;

	import flash.errors.IllegalOperationError;
	import flash.events.ErrorEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;

	import starling.events.Event;

	/**
	 * Dispatched when the MP3 ID3 metadata becomes available on the
	 * Sound instance.
	 *
	 * 

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataThe flash.media.ID3Info * instance returned by the id3 property of the * Sound instance.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#id3 flash.media.Sound.id3 * * @eventType feathers.events.MediaPlayerEventType.METADATA_RECEIVED */ [Event(name="metadataReceived",type="starling.events.Event")] /** * Dispatched periodically when a media player's content is loading to * indicate the current progress. The bytesLoaded and * bytesTotal properties may be accessed to determine the * exact number of bytes loaded. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataA numeric value between 0 * and 1 that indicates how much of the media has loaded so far.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see #bytesLoaded * @see #bytesTotal * * @eventType feathers.events.MediaPlayerEventType.LOAD_PROGRESS */ [Event(name="loadProgress",type="starling.events.Event")] /** * Dispatched when a media player's content is fully loaded and it * may be played to completion without buffering. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
datanull
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see #isLoaded * * @eventType feathers.events.MediaPlayerEventType.LOAD_COMPLETE */ [Event(name="loadComplete",type="starling.events.Event")] /** * Dispatched when the flash.media.Sound object dispatches * flash.events.IOErrorEvent.IO_ERROR. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataThe flash.events.IOErrorEvent * dispatched by the flash.media.Sound.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#event:ioError flash.media.Sound: flash.events.IOErrorEvent.IO_ERROR * * @eventType starling.events.Event.IO_ERROR */ [Event(name="ioError",type="starling.events.Event")] /** * Dispatched when the flash.media.Sound object dispatches * flash.events.SecurityErrorEvent.SECURITY_ERROR. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataThe flash.events.SecurityErrorEvent * dispatched by the flash.media.Sound.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#event:securityError flash.media.Sound: flash.events.SecurityErrorEvent.SECURITY_ERROR * * @eventType starling.events.Event.SECURITY_ERROR */ [Event(name="securityError",type="starling.events.Event")] /** * Dispatched when the media player's sound transform changes. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
datanull
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @see #soundTransform * * @eventType feathers.events.MediaPlayerEventType.SOUND_TRANSFORM_CHANGE */ [Event(name="soundTransformChange",type="starling.events.Event")] /** * Controls playback of audio with a flash.media.Sound object. * *

Beta Component: This is a new component, and its APIs * may need some changes between now and the next version of Feathers to * account for overlooked requirements or other issues. Upgrading to future * versions of Feathers may involve manual changes to your code that uses * this component. The * Feathers deprecation policy * will not go into effect until this component's status is upgraded from * beta to stable.

* * @see ../../../help/sound-player.html How to use the Feathers SoundPlayer component */ public class SoundPlayer extends BaseTimedMediaPlayer implements IAudioPlayer, IProgressiveMediaPlayer { /** * @private */ protected static const NO_SOUND_SOURCE_PLAY_ERROR:String = "Cannot play media when soundSource property has not been set."; /** * The default IStyleProvider for all * SoundPlayer components. * * @default null * @see feathers.core.FeathersControl#styleProvider */ public static var globalStyleProvider:IStyleProvider; /** * Constructor. */ public function SoundPlayer() { super(); } /** * @private */ override protected function get defaultStyleProvider():IStyleProvider { return SoundPlayer.globalStyleProvider; } /** * @private */ protected var _sound:Sound; /** * The flash.media.Sound object that has loaded the * content specified by soundSource. * * @see #soundSource */ public function get sound():Sound { return this._sound; } /** * @private */ protected var _soundChannel:SoundChannel; /** * The currently playing flash.media.SoundChannel. */ public function get soundChannel():SoundChannel { return this._soundChannel; } /** * @private */ protected var _soundSource:Object; /** * A URL specified as a String representing a URL, a * flash.net.URLRequest, or a * flash.media.Sound object. In the case of a * String or a URLRequest, a new * flash.media.Sound object will be created internally and * the content will by loaded automatically. * *

In the following example, a sound file URL is passed in:

* * * soundPlayer.soundSource = "http://example.com/sound.mp3"; * * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequest.html flash.net.URLRequest * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html flash.media.Sound */ public function get soundSource():Object { return this._soundSource; } /** * @private */ public function set soundSource(value:Object):void { if(this._soundSource === value) { return; } if(this._isPlaying) { this.stop(); } this._soundSource = value; //reset the current and total time if we were playing a different //sound previously if(this._currentTime !== 0) { this._currentTime = 0; this.dispatchEventWith(MediaPlayerEventType.CURRENT_TIME_CHANGE); } if(this._totalTime !== 0) { this._totalTime = 0; this.dispatchEventWith(MediaPlayerEventType.TOTAL_TIME_CHANGE); } if(this._sound) { this.cleanupSound(); } this._isLoaded = false; if(this._soundSource is String) { this.loadSourceFromURL(value as String); } else if(this._soundSource is URLRequest) { this.loadSourceFromURLRequest(URLRequest(value)); } else if(this._soundSource is Sound) { this._sound = Sound(this._soundSource); var newTotalTime:Number = this._sound.length / 1000; if(this._totalTime !== newTotalTime) { this._totalTime = newTotalTime; this.dispatchEventWith(MediaPlayerEventType.TOTAL_TIME_CHANGE); } if(this._sound.isBuffering) { this._sound.addEventListener(IOErrorEvent.IO_ERROR, sound_errorHandler); this._sound.addEventListener(ProgressEvent.PROGRESS, sound_progressHandler); this._sound.addEventListener(flash.events.Event.COMPLETE, sound_completeHandler); this._sound.addEventListener(flash.events.Event.ID3, sound_id3Handler); } } else if(this._soundSource === null) { this._sound = null; } else { throw new ArgumentError("Invalid source type for SoundPlayer. Expected a URL as a String, an URLRequest, a Sound object, or null.") } if(this._autoPlay && this._sound) { this.play(); } } /** * @private */ protected var _isLoading:Boolean = false; /** * Indicates if the flash.media.Sound object is currently * loading its content. */ public function get isLoading():Boolean { return this._isLoading; } /** * @private */ protected var _isLoaded:Boolean = false; /** * Indicates if the flash.media.Sound object has finished * loading its content. * * @see #event:loadProgress feathers.events.MediaPlayerEventType.LOAD_PROGRESS * @see #event:loadComplete feathers.events.MediaPlayerEventType.LOAD_COMPLETE */ public function get isLoaded():Boolean { return this._isLoaded; } /** * @copy feathers.media.IProgressiveMediaPlayer#bytesLoaded * * @see #bytesTotal * @see #event:loadProgress feathers.events.MediaPlayerEventType.LOAD_PROGRESS */ public function get bytesLoaded():uint { if(!this._sound) { return 0; } return this._sound.bytesLoaded; } /** * @copy feathers.media.IProgressiveMediaPlayer#bytesTotal * * @see #bytesLoaded * @see #event:loadProgress feathers.events.MediaPlayerEventType.LOAD_PROGRESS */ public function get bytesTotal():uint { if(!this._sound) { return 0; } return this._sound.bytesTotal; } /** * @private */ protected var _soundTransform:SoundTransform; /** * @inheritDoc * *

In the following example, the audio is muted:

* * * soundPlayer.soundTransform = new SoundTransform(0); * * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundTransform.html flash.media.SoundTransform * @see #event:soundTransformChange feathers.events.MediaPlayerEventType.SOUND_TRANSFORM_CHANGE */ public function get soundTransform():SoundTransform { if(!this._soundTransform) { this._soundTransform = new SoundTransform(); } return this._soundTransform; } /** * @private */ public function set soundTransform(value:SoundTransform):void { this._soundTransform = value; if(this._soundChannel) { this._soundChannel.soundTransform = this._soundTransform; } this.dispatchEventWith(MediaPlayerEventType.SOUND_TRANSFORM_CHANGE); } /** * @private */ protected var _autoPlay:Boolean = true; /** * Determines if the sound starts playing immediately when the * soundSource property is set. * *

In the following example, automatic playback is disabled:

* * * soundPlayer.autoPlay = false; * * @see #soundSource */ public function get autoPlay():Boolean { return this._autoPlay; } /** * @private */ public function set autoPlay(value:Boolean):void { this._autoPlay = value; } /** * @private */ protected var _loop:Boolean = false; /** * Determines if, upon reaching the end of the sound, the playhead * automatically returns to the start of the media and plays again. * *

If loop is true, the * autoRewind property will be ignored because looping will * always automatically rewind to the beginning.

* *

In the following example, looping is enabled:

* * * soundPlayer.loop = true; */ public function get loop():Boolean { return this._loop; } /** * @private */ public function set loop(value:Boolean):void { this._loop = value; } /** * @private */ override public function dispose():void { this.soundSource = null; super.dispose(); } /** * @private */ override public function play():void { if(this._sound === null) { return; } super.play(); } /** * @private */ override protected function playMedia():void { if(!this._soundSource) { throw new IllegalOperationError(NO_SOUND_SOURCE_PLAY_ERROR); } if(!this._sound.isBuffering && this._currentTime == this._totalTime) { //flash.events.Event.SOUND_COMPLETE may not be dispatched (or //maybe it is dispatched, but before the listener can be added) //if currentTime is equal to totalTime, so we need to do it //manually. this.handleSoundComplete(); return; } if(!this._soundTransform) { this._soundTransform = new SoundTransform(); } this._soundChannel = this._sound.play(this._currentTime * 1000, 0, this._soundTransform); this._soundChannel.addEventListener(flash.events.Event.SOUND_COMPLETE, soundChannel_soundCompleteHandler); this.addEventListener(starling.events.Event.ENTER_FRAME, soundPlayer_enterFrameHandler); } /** * @private */ override protected function pauseMedia():void { if(!this._soundChannel) { //this could be null when seeking return; } this.removeEventListener(starling.events.Event.ENTER_FRAME, soundPlayer_enterFrameHandler); this._soundChannel.stop(); this._soundChannel.removeEventListener(flash.events.Event.SOUND_COMPLETE, soundChannel_soundCompleteHandler); this._soundChannel = null; } /** * @private */ override protected function seekMedia(seconds:Number):void { this.pauseMedia(); this._currentTime = seconds; if(this._isPlaying) { this.playMedia(); } } /** * @private */ protected function handleSoundComplete():void { //return to the beginning this.stop(); this.dispatchEventWith(starling.events.Event.COMPLETE); if(this._loop) { this.play(); } } /** * @private */ protected function loadSourceFromURL(url:String):void { this.loadSourceFromURLRequest(new URLRequest(url)); } /** * @private */ protected function loadSourceFromURLRequest(request:URLRequest):void { this._isLoading = true; if(this._sound) { this.cleanupSound(); } this._sound = new Sound(); this._sound.addEventListener(IOErrorEvent.IO_ERROR, sound_errorHandler); this._sound.addEventListener(ProgressEvent.PROGRESS, sound_progressHandler); this._sound.addEventListener(flash.events.Event.COMPLETE, sound_completeHandler); this._sound.addEventListener(flash.events.Event.ID3, sound_id3Handler); this._sound.load(request); } /** * @private */ protected function cleanupSound():void { if(!this._sound) { return; } this._sound.removeEventListener(IOErrorEvent.IO_ERROR, sound_errorHandler); this._sound.removeEventListener(ProgressEvent.PROGRESS, sound_progressHandler); this._sound.removeEventListener(flash.events.Event.COMPLETE, sound_completeHandler); this._sound.removeEventListener(flash.events.Event.ID3, sound_id3Handler); this._sound = null; } /** * @private */ protected function soundPlayer_enterFrameHandler(event:starling.events.Event):void { this._currentTime = this._soundChannel.position / 1000; this.dispatchEventWith(MediaPlayerEventType.CURRENT_TIME_CHANGE); } /** * @private * This isn't when the sound finishes playing. It's when the sound has * finished loading. */ protected function sound_completeHandler(event:flash.events.Event):void { this._totalTime = this._sound.length / 1000; this.dispatchEventWith(MediaPlayerEventType.TOTAL_TIME_CHANGE); this._isLoading = false; this._isLoaded = true; this.dispatchEventWith(MediaPlayerEventType.LOAD_COMPLETE); } /** * @private */ protected function sound_id3Handler(event:flash.events.Event):void { this.dispatchEventWith(MediaPlayerEventType.METADATA_RECEIVED, false, this._sound.id3); } /** * @private */ protected function sound_progressHandler(event:ProgressEvent):void { var oldTotalTime:Number = this._totalTime; this._totalTime = this._sound.length / 1000; if(oldTotalTime !== this._totalTime) { this.dispatchEventWith(MediaPlayerEventType.TOTAL_TIME_CHANGE); } this.dispatchEventWith(MediaPlayerEventType.LOAD_PROGRESS, false, event.bytesLoaded / event.bytesTotal); } /** * @private */ protected function sound_errorHandler(event:ErrorEvent):void { //since it's just a string in both cases, we'll reuse event.type for //the Starling event. this.dispatchEventWith(event.type, false, event); } /** * @private */ protected function soundChannel_soundCompleteHandler(event:flash.events.Event):void { this.handleSoundComplete(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy