SimpleMP3Player
Sound.loadCompressedDataFromByteArray を使用してとりあえず作ってみました
/**
* Copyright okoi ( http://wonderfl.net/user/okoi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/hI52
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.ByteArray;
[SWF(width = "465", height = "465", frameRate="60")]
/**
* ...
* @author okoi
*/
public class Main extends Sprite
{
public static const WIDTH:int = 465;
public static const HEIGHT:int = 465;
private var _progressbar:ProgressBar;
private var _player:SimpleMP3Player;
private var _canvas:Sprite;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
graphics.beginFill(0);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
_canvas = new Sprite();
addChild( _canvas );
_player = new SimpleMP3Player( LoadStart, LoadEnd );
_player.x = WIDTH / 2;
_player.y = 0;
addChild( _player );
addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
private function LoadStart() : void {
LoadEnd();
_progressbar = new ProgressBar();
_progressbar.x = WIDTH / 2;
_progressbar.y = HEIGHT / 2;
addChild( _progressbar );
}
private function LoadEnd() : void {
if( _progressbar ){
removeChild( _progressbar );
_progressbar = null;
}
}
private function EnterFrameHandler( e:Event ) : void {
var buf:Array = _player.GetSpectrumData();
_canvas.graphics.clear();
_canvas.graphics.lineStyle( 1, 0xFFFFFF );
for ( var i:int = 0; i < buf.length; i++ ) {
var val:Number = buf[i] * 100;
if ( i == 0 ) _canvas.graphics.moveTo(WIDTH / 2 - buf.length / 2 + i, HEIGHT / 2 - val);
else _canvas.graphics.lineTo(WIDTH/2 - buf.length/2 + i, HEIGHT/2 - val);
}
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ProgressEvent;
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
/**
* ...
* @author okoi
*/
class ProgressBar extends Sprite
{
private var _mask:Shape;
private var text:TextField;
private var ct:int;
private static const PARTICLE_LIFE:int = 60;
private var particleList:/*Object*/Array;
private var _rate:Number = 0;
public function ProgressBar()
{
ct = 0;
particleList = [];
var format:TextFormat = new TextFormat();
format.font = "Arial";
format.bold = true;
format.color = 0xFFFFFF;
text = new TextField();
text.defaultTextFormat = format;
text.text = "LOADING";
text.selectable = false;
text.x = -text.textWidth / 2;
text.y = -text.textHeight / 2;
addChild( text );
_mask = new Shape();
_mask.graphics.beginFill(0);
_mask.graphics.drawRect( -100, -25, 200, 50 );
_mask.graphics.endFill();
this.mask = _mask;
addChild( _mask );
addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
public function Destroy() : void {
removeEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
private function EnterFrameHandler( e:Event ) : void {
var g:Graphics = graphics;
g.clear();
if ( int(Math.random() * 10) == 0 ) AddParticle();
for ( var i:int = particleList.length - 1; i >= 0; i-- ) {
g.lineStyle( 2, 0xFFFFFF, 0.5 - (1 - particleList[i].life / PARTICLE_LIFE) * 0.5 );
particleList[i].y += particleList[i].vy;
particleList[i].life -= 1;
g.drawCircle( particleList[i].x, particleList[i].y, particleList[i].radius );
if ( particleList[i].life == 0 ) {
particleList.splice( i, 1 );
}
}
if( ct % 4 == 0 ) text.alpha = 0;
else text.alpha = 0.5;
ct++;
}
private function AddParticle() : void
{
var particle:Object = new Object();
particle.x = Math.random() * 100 - 50;
particle.y = 35;
particle.radius = Math.random() * 5 + 5;
particle.vy = (Math.random() * 1 + 0.5) * -1;
particle.life = PARTICLE_LIFE;
particleList.push( particle );
}
public function set rate( val:Number ) : void { _rate = val; }
}
/**
* ...
* @author okoi
*/
class SimpleMP3Player extends Sprite
{
public static const WIDTH:int = 450;
public static const HEIGHT:int = 50;
private var _bytes:ByteArray;
private var _fr:FileReference;
private var _sound:Sound = null;
private var _soundChannel:SoundChannel = null;
private var _pausePosition:Number;
private var _loadStartCallback:Function/*():void*/;
private var _loadEndCallback:Function/*():void*/;
private var _btn_play:Button;
private var _flg_play:Boolean = false;
private var _btn_load:Button;
private var _flg_loading:Boolean;
private var _titleBoard:TitleBoard;
public function SimpleMP3Player( loadstartcallback:Function, loadendcallback:Function )
{
_fr = new FileReference();
_fr.addEventListener( Event.SELECT, FileSelectHandler );
_fr.addEventListener( ProgressEvent.PROGRESS, ProgressHandler );
_fr.addEventListener( Event.COMPLETE, FileLoadCompleteHandler );
_fr.addEventListener( IOErrorEvent.IO_ERROR, FileLoadIOErrorHandler );
_fr.addEventListener( SecurityErrorEvent.SECURITY_ERROR, FileLoadSecurityError );
_flg_loading = false;
_bytes = new ByteArray();
_loadStartCallback = loadstartcallback;
_loadEndCallback = loadendcallback;
CreateUI();
}
private function OpenFileSelectDialog() : void {
var filter:FileFilter = new FileFilter("mp3 file", "*.mp3");
_fr.browse([filter]);
}
private function FileSelectHandler( e:Event ) : void {
_fr.load();
_flg_loading = true;
_btn_play.Selectable( false );
_titleBoard.SetTitle("");
if( _loadStartCallback != null ) _loadStartCallback();
}
private function ProgressHandler( e:ProgressEvent ) : void {
}
private function FileLoadCompleteHandler( e:Event ) : void {
_flg_loading = false;
_pausePosition = 0;
_sound = new Sound();
_sound.loadCompressedDataFromByteArray( _fr.data, _fr.data.length );
SetTitleBoardText( _fr.name );
resetSoundChannel();
_btn_play.Selectable( true );
_flg_play = true;
onClickPlayButton();
if ( _loadEndCallback != null ) _loadEndCallback();
}
private function FileLoadIOErrorHandler( e:IOErrorEvent ) : void {
_flg_loading = false;
_sound = null;
changePlayButton( false );
_btn_play.Selectable( false );
}
private function FileLoadSecurityError( e:SecurityErrorEvent ) : void {
_flg_loading = false;
_sound = null;
changePlayButton( false );
_btn_play.Selectable( false );
}
private function resetSoundChannel() : void {
if ( _soundChannel != null ) {
_soundChannel.stop();
_soundChannel.removeEventListener( Event.SOUND_COMPLETE, SoundCompleteHandler );
_soundChannel = null;
}
_titleBoard.SetScrollFlag( false );
}
/**
* サウンドの再生、再開を行う
*/
private function play() : void {
if ( _sound ) {
_soundChannel = _sound.play( _pausePosition );
_soundChannel.addEventListener( Event.SOUND_COMPLETE, SoundCompleteHandler );
_pausePosition = 0;
_titleBoard.SetScrollFlag( true );
}
}
/**
* サウンドの一時停止を行う
*/
private function pause() : void {
if ( _soundChannel ) {
_pausePosition = _soundChannel.position;
resetSoundChannel();
}
}
private function SoundCompleteHandler( e:Event ) : void {
_pausePosition = 0;
resetSoundChannel();
play();
}
public function GetSpectrumData() : Array
{
var i:int;
var buf:Array = new Array(512);
if ( !_soundChannel )
{
for ( i = 0; i < 512; i++ ) buf[i] = 0;
return buf;
}
SoundMixer.computeSpectrum( _bytes, true, 0 );
_bytes.position = 0;
for ( i = 0; i < 512; i++ ) buf[i] = _bytes.readFloat();
return buf;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
private function CreateUI() : void {
var g:Graphics;
g = graphics;
// 背景
CreatePlayButton();
CreateLoadButton();
CreateTitleBoard();
}
private function CreatePlayButton() : void {
_btn_play = new Button( 58, 18, "play", onClickPlayButton );
_btn_play.x = -35;
_btn_play.y = 20;
_btn_play.Selectable( false );
addChild( _btn_play );
}
/**
* 再生ボタンが押された
*/
private function onClickPlayButton() : void {
_flg_play = ( _flg_play ) ? false : true;
changePlayButton( _flg_play );
if ( _flg_play ) {
play();
}else {
pause();
}
}
private function changePlayButton( flg:Boolean ) : void {
if ( flg ) {
_btn_play.setLabelText( "stop" );
}else {
_btn_play.setLabelText( "play" );
}
}
/**
* 曲ロードボタンを作成
*/
private function CreateLoadButton() : void {
_btn_load = new Button( 58, 18, "load", onClickLoadButton );
_btn_load.x = 35;
_btn_load.y = 20;
addChild( _btn_load );
}
/**
* 曲ロードボタンが押された
*/
private function onClickLoadButton() : void {
if ( _flg_loading ) return;
OpenFileSelectDialog();
}
private function CreateTitleBoard() : void {
_titleBoard = new TitleBoard();
_titleBoard.x = -TitleBoard.WIDTH / 2;
_titleBoard.y = 40;
addChild( _titleBoard );
}
private function SetTitleBoardText( text:String ) : void {
_titleBoard.SetTitle(text);
}
}
class Button extends Sprite {
private var label:TextField;
private var _onclick:Function/*():void*/ = null;
private var _width:Number;
private var _height:Number;
private var _selectable:Boolean;
public function Button( w:Number, h:Number, text:String, onclick:Function ) {
graphics.lineStyle( 1, 0x474a4d );
graphics.beginFill( 0x2b2b2b );
graphics.drawRect( -w/2, -h/2, w, h );
graphics.endFill();
_width = w;
_height = h;
var tf:TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 12;
tf.color = 0xFFFFFF;
tf.align = TextFormatAlign.CENTER;
label = new TextField();
label.mouseEnabled = false;
label.autoSize = "center";
label.multiline = false;
label.defaultTextFormat = tf;
label.selectable = false;
label.text = text;
label.x = -w/2;
label.y = -h/2;
label.width = w;
label.height = h;
addChild( label );
this._onclick = onclick;
this.buttonMode = true;
this.addEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
}
private function MouseDownHandler( e:MouseEvent ) : void {
this.removeEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
this.addEventListener( MouseEvent.MOUSE_UP, MouseUpHandler );
this.addEventListener( MouseEvent.ROLL_OUT, RollOutHandler );
ChangeColor( true );
}
private function MouseUpHandler( e:MouseEvent ) : void {
this.removeEventListener( MouseEvent.MOUSE_UP, MouseUpHandler );
this.removeEventListener( MouseEvent.ROLL_OUT, RollOutHandler );
this.addEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
ChangeColor(false);
if ( _onclick != null ) {
_onclick();
}
}
private function RollOutHandler( e:MouseEvent ) : void {
this.removeEventListener( MouseEvent.MOUSE_UP, MouseUpHandler );
this.removeEventListener( MouseEvent.ROLL_OUT, RollOutHandler );
this.addEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
ChangeColor(false);
}
private function ChangeColor( press:Boolean ) : void {
graphics.clear();
graphics.lineStyle( 1, 0x474a4d );
if ( press ) {
graphics.beginFill( 0x727171 );
}else {
graphics.beginFill( 0x2b2b2b );
}
graphics.drawRect( -_width/2, -_height/2, _width, _height );
graphics.endFill();
}
public function setLabelText( text:String ) : void {
label.text = text;
}
public function Selectable( flg:Boolean ) : void {
_selectable = flg;
this.mouseChildren = flg;
this.mouseEnabled = flg;
if ( !flg ) {
ChangeColor(false);
this.alpha = 0.5;
}else {
this.alpha = 1;
}
}
}
class TitleBoard extends Sprite {
public static const WIDTH:int = 300;
public static const HEIGHT:int = 20;
private var text:TextField;
private var _mask:Shape;
private var _flg_scroll:Boolean;
public function TitleBoard() {
this.alpha = 0.5;
graphics.lineStyle( 1, 0x474a4d );
graphics.beginFill( 0xc0c6c9 );
graphics.drawRect( 0, 0, WIDTH, HEIGHT );
graphics.endFill();
var tf:TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 14;
tf.color = 0xFFFFFF;
tf.align = TextFormatAlign.CENTER;
text = new TextField();
text.autoSize = "left";
text.selectable = false;
text.defaultTextFormat = tf;
text.x = WIDTH / 2;
addChild( text );
_mask = new Shape();
_mask.graphics.beginFill(0);
_mask.graphics.drawRect(0, 0, WIDTH, HEIGHT);
_mask.graphics.endFill();
this.mask = _mask;
addChild( _mask );
_flg_scroll = false;
addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
public function SetTitle( title:String ) : void {
text.text = title;
text.x = WIDTH / 2 - text.textWidth / 2;
}
private function EnterFrameHandler( e:Event ) : void {
//if ( text.textWidth >= WIDTH ) {
if( _flg_scroll ) {
text.x -= 1;
if ( text.x < -text.textWidth ) {
text.x = WIDTH;
}
}
}
public function SetScrollFlag( flg:Boolean ) : void {
_flg_scroll = flg;
}
}