MP3をロードして再生するサンプルです。
スペクトラムの表示はおまけ。
サンプルはこちら。
UIにはminimalcompsを使っています。
MP3ファイルはこちらのものを使わせてもらってます。
以下、ソースです。
package
{
import com.bit101.components.HSlider;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Rectangle;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.media.SoundMixer;
import flash.media.SoundTransform;
import flash.net.URLRequest;
import flash.utils.ByteArray;
[SWF(backgroundColor="0xFFFFFF")]
public class sound_player extends Sprite
{
private var sound:Sound;
private var channel:SoundChannel;
private var canvas:BitmapData;
private var totalTime:Number;
private var position:int;
private var seekBar:Sprite;
private var seekBtn:Sprite;
private var seekRect:Rectangle;
private var volumeSlider:HSlider;
private var playing:int;
private var playTimeLabel:Label;
private var totalTimeLabel:Label;
private var volumeLabel:Label;
private var seeking:Boolean;
private var bytes:ByteArray;
private var errorLabel:Label;
public function sound_player()
{
// ステージの設定
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.align=StageAlign.TOP_LEFT;
stage.quality=StageQuality.HIGH;
stage.frameRate=40;
// mp3のロード
sound=new Sound;
sound.addEventListener(Event.COMPLETE, onComplete);
var req:URLRequest=new URLRequest("MP3ファイルまでのパス");
sound.load(req, new SoundLoaderContext(1000, true));
}
private function onComplete(e:Event):void
{
sound.removeEventListener(Event.COMPLETE, onComplete);
// BitmapDataの用意
canvas=new BitmapData(512, 300, false, 0xffffff);
var bmp:Bitmap=new Bitmap(canvas);
addChild(bmp);
bmp.x=bmp.y=100;
// BitmapDataの枠線
var frame:Shape=new Shape;
frame.graphics.lineStyle(1, 0xAAAAAA);
frame.graphics.drawRect(0, 0, 512, 300);
frame.graphics.endFill();
addChild(frame);
frame.x=frame.y=100;
// エラー用ラベル
errorLabel=new Label(this, 250, 200, "Error.\n\nCannot get Sound wave data.\nYou may open FLV video (YouTube etc..) in other tabs.");
// 再生フラグの初期化 0:停止 1:再生 2:一時停止
playing=1;
// 諸々の初期化
position=0;
seeking=false;
seekRect=new Rectangle(0, 0, 340, 0);
bytes=new ByteArray();
// 再生、一時停止、停止用のボタン
var playBtn:PushButton=new PushButton(this, 650, 100, "PLAY", onPlay);
var pauseBtn:PushButton=new PushButton(this, 770, 100, "PAUSE", onPause);
var stopBtn:PushButton=new PushButton(this, 890, 100, "STOP", onStop);
// 再生時間と音量を表示するラベル
volumeLabel=new Label(this, 650, 133, "Volume: 50%");
playTimeLabel=new Label(this, 650, 175, "Time:00:00");
totalTimeLabel=new Label(this, 700, 175, "");
// 音量用スライダー
volumeSlider=new HSlider(this, 650, 150, onSeekVolume);
volumeSlider.width=340;
volumeSlider.value=50;
volumeSlider.maximum=100
volumeSlider.minimum=0;
// シークバー
seekBar=new Sprite;
seekBar.graphics.lineStyle(1, 0xAAAAAA);
seekBar.graphics.drawRect(0, -5, 340, 10);
seekBar.graphics.endFill();
addChild(seekBar);
seekBar.x=650;
seekBar.y=200;
// シークバーのボタン
seekBtn=new Sprite;
seekBtn.graphics.beginFill(0x666666);
seekBtn.graphics.drawRect(-3, -8, 6, 16);
seekBtn.graphics.endFill();
seekBtn.filters=[new DropShadowFilter(2, 45, 0x444444, 0.5, 2, 3)]
seekBar.addChild(seekBtn);
// シークバーのボタンのドラッグ範囲
seekRect=new Rectangle(0, 0, 340, 0);
// 再生
channel=sound.play();
totalTime=sound.length;
onSeekVolume();
totalTimeLabel.text=" / " + createTimeText((totalTime / 1000) >> 0);
addEventListener(Event.ENTER_FRAME, onFrame);
// シーク用
seekBtn.addEventListener(MouseEvent.MOUSE_DOWN, onStartSeek);
stage.addEventListener(MouseEvent.MOUSE_UP, onStopSeek);
}
// 再生用関数
private function onPlay(e:Event):void
{
if (playing != 1)
{
channel=sound.play(position);
playing=1;
}
}
// 一時停止用関数
private function onPause(e:Event):void
{
if (playing == 1)
{
channel.stop();
playing=2;
position=channel.position;
canvas.fillRect(canvas.rect, 0xffffff);
}
}
// 停止用関数
private function onStop(e:Event):void
{
if (playing != 0)
{
channel.stop();
playing=0;
position=0;
canvas.fillRect(canvas.rect, 0xffffff);
}
}
// 音量調整用関数
private function onSeekVolume(e:Event=null):void
{
if (channel)
{
var transform:SoundTransform=channel.soundTransform;
transform.volume=Number(volumeSlider.value / 100);
channel.soundTransform=transform;
volumeLabel.text="Volume: " + volumeSlider.value.toString() + "%";
}
}
// フレームイベント用関数
private function onFrame(e:Event):void
{
// 再生位置の更新
position=(playing == 1 && channel) ? (channel.position) : (position);
// シークの位置更新
if (seeking)
{
position=(totalTime * seekBtn.x / 340) >> 0;
if (playing == 1)
{
if (channel) channel.stop();
channel=sound.play(position);
}
}
else
seekBtn.x=340 * position / totalTime;
// 時間をmm:ssの形に整形
var t:String=createTimeText((position / 1000) >> 0);
playTimeLabel.text="Time:" + t;
// スペクトラムの作成
canvas.fillRect(canvas.rect, 0xffffff);
if (playing == 1)
{
if (!SoundMixer.areSoundsInaccessible())
{
errorLabel.visible=false;
canvas.lock();
SoundMixer.computeSpectrum(bytes, true, 0);
var spec:Number;
var h:Number;
var step:int;
var j:int;
for(var i:int=0; i < 256; ++i)
{
spec=bytes.readFloat();
h=400 * spec;
h=(h > 300) ? (300) : (h);
step=(h / 2) >> 0;
for(j=0; j < step; j++) canvas.setPixel(2 * i, 300 - 2 * j, 0x888888);
}
canvas.unlock();
}
else errorLabel.visible=true;
}
}
// シーク開始用関数
private function onStartSeek(e:MouseEvent):void
{
if (!seeking)
{
seeking=true;
seekBtn.startDrag(false, seekRect);
}
}
// シーク終了用関数
private function onStopSeek(e:MouseEvent):void
{
if (seeking)
{
seeking=false;
seekBtn.stopDrag();
}
}
// 秒数を時間表示用 mm:ss に整形する関数
private function createTimeText(time:int):String
{
var m:int=(time / 60) >> 0;
var s:int=(time % 60) >> 0;
var str:String=((m < 10) ? ("0" + m.toString()) : (m.toString()));
str+=":" + ((s < 10) ? ("0" + s.toString()) : (s.toString()));
return str;
}
}
}
