◆PROCESSING 逆引きリファレンス
カテゴリー:スマホ(AndroidMode)
音楽を演奏するには(AndroidMode編)
【概要】
PROCESSINGにAndroidMode を導入する事で、PROCESSINGで開発したプログラムをAndroid端末上で動かす事ができるようになります。
AndroidModeの導入については「PROCESSINGをAndroid端末で動かすには(4.0版)」記事を参照してください。
AndroidModeで音楽や効果音を演奏するには、Android SDK が提供している命令を使う事になります。※
- 効果音:SoundPool を利用する
- BGM:MediaPlayer を利用する
※この他にも JetPlayer クラスや AudioTrack クラスを使う方法があります。
鳴らしたい音が音楽(BGMなど)なのか効果音なのかにより、利用する命令が異なります。
SoundPoolについては「効果音を鳴らすには(AndroidMode編)」を参照して下さい。
MediaPlayerクラスを使うとBGMの再生を行うことが可能です。また動画再生なども行えるようです。動画再生については、そのうち別記事にしたいと思います。
MediaPlayerの使い方については、以下の記事などが参考となりました。ありがとうございます。
- nyanのアプリ開発 様:[Android] 簡単なMediaPlayerで音楽を再生する
- @IT 様:Androidアプリでマルチメディアを扱うための基礎知識
- Kazuko Yamasaki’s Page 様
MediaPlayerはオートマトンのような状態遷移を持っており、状態に応じた適切な命令を利用しないと例外を発生します。
以下は 公式サイト にある状態遷移図の抜粋です。
状態名 | 遷移命令 | 説明 |
---|---|---|
Idle | new reset |
new で MediaPlayerを生成した直後の状態です。resetメソッド実行時も、この状態に遷移します。MediaPlayer.create でオブジェクトを生成した場合は、生成が完了すると、Initialized 状態を飛ばして Prepared 状態に遷移します。 |
Initialized | setDataSource | 再生する音楽データを割り当てた状態です。ただし、まだデータの読み込みは行われていません。 |
Prepared | prepare create |
再生する音楽データを読み込んだ状態です。再生可能な状態という事ですね。 prepare は同期読み込みのため、大きなサイズの音楽データは処理に時間がかかります。そのようなデータを扱うなら、非同期読み込み命令(prepareAsync)を利用した方が良いでしょう。 |
Preparing | prepareAsync | 再生する音楽データを読み込み中の状態です。Initialized状態から非同期読み込み命令(prepareAsync)を利用した場合、この状態になります。prepareAsyncを実行する前に setOnPreparedListener でリスナーを登録しておくと、データの読み込み完了を検知可能です。非同期読み込みを行う場合は、リスナー登録は必須ですね。 |
Started | start | 音楽再生中です。再生する前に setCompletionListener でリスナーを登録しておくと、再生完了を検知可能です。再生中か否かは isPlaying メソッドを利用することでも知ることが出来ます。 |
Paused | pause | 再生中断状態です。start で演奏している途中で pause メソッドを実行すると、この状態になります。この状態から再度 start メソッドを実行すれば、曲の再生を再開します。 |
Stopped | stop | 再生停止状態です。prepare、start または pause 状態から stop メソッドを実行すると、この状態になります。この状態から再度演奏を開始するには prepare または prepareAsync を実行し、曲データを読み直す必要があります。 |
PlaybackCompleted | なし(再生終了) | ループ(繰り返し)再生中ではなく、かつ setCompletionListener で再生完了を検知するリスナーを登録していた場合、曲の演奏が終わるとこの状態になります。この状態から再度 start メソッドを利用すると、曲の頭から再生が始まります。 |
End | release | オブジェクトの利用が終了した状態です。これ以上なにもできません。MediaPlayerは、アプリケーション終了時に必ず release して、この状態にする必要があります。 |
Error | なし(予期せぬタイミング) | OnErrorListenerを定義していた場合、エラーを検知するとこの状態になります。 |
状態遷移が複雑で、かつアプリケーション側で状態を管理する必要がある所が面倒くさいのですが、シンプルに使うだけなら意外とお手軽です。
MediaPlayerには2種類のオブジェクト生成方法が提供されています。
new で素直に生成する方法と、create メソッドで生成する方法です。create で生成した方が1つ手順が省けるので楽ですが、指定した音楽ファイルを必ず同期読み込みするようなので、大きなファイルを扱う場合は注意が必要です。
【詳細】
オブジェクト生成
コンストラクタで生成するMediaPlayer mp = new MediaPlayer( ) ;
mp : MediaPlayer インスタンス
MediaPlayerを生成します。new で生成した場合は、Idle 状態になります。
create 命令で生成するMediaPlayer mp = MediaPlayer . create( Context context, int resid ) ;
mp : MediaPlayer インスタンス
context : コンテキスト
resid : 音楽ファイルのリソースID
インスタンス生成時に音楽ファイルを指定することが可能です。ceate メソッドで生成すると、指定ファイルが割り当てられて読み込まれ Prepared 状態になります。
音楽データ割当
void mp . setDataSource ( FileDescriptor fd, long offset, long length ) ;
void mp . setDataSource ( Context context, Uri uri ) ;
mp : MediaPlayer インスタンス
path : 音楽ファイルへのパス
fd : ファイル識別子
offset : 開始位置
length : ファイルサイズ
context : コンテキスト
uri : 音楽ファイルへのURIパス
音楽ファイルを割り当てます。割当が完了すると Initialized 状態になります。
音楽ファイルが外部ストレージ(SDカードなど)にある場合、Assetsフォルダにある場合、resフォルダのrawにある場合(およびWeb上にある場合)用の命令が上記になります。
以下、それぞれのケースにおける music.ogg という名前の音楽ファイルの割当例を紹介します。
●外部ストレージ(SDカードなど)にある場合の割当例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Activity act = getActivity(); Context con = act.getApplicationContext(); MediaPlayer mp = new MediaPlayer(); //外部ストレージ(SDカードなど)から音楽ファイルを得る String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + "music.ogg"; try{ mp.setDataSource(filePath); } catch( IOException e){ //例外 throw new IllegalStateException( MessageFormat.format( "setDataSource error: msg={0}, value={1}", e.getMessage(), e.getStackTrace())); } |
●Assetsフォルダにある場合の割当例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
Activity act = getActivity(); Context con = act.getApplicationContext(); MediaPlayer mp = new MediaPlayer(); //アセットから音楽ファイルを得る AssetManager assetManager = act.getResources().getAssets(); AssetFileDescriptor fd; try{ fd = assetManager.openFd("music.ogg"); } catch( IOException e){ //例外 throw new IllegalStateException( MessageFormat.format( "assetManager openFd error: msg={0}, value={1}", e.getMessage(), e.getStackTrace())); } try { mp.setDataSource( fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); }catch( IOException e){ //例外 throw new IllegalStateException( MessageFormat.format( "setDataSource error: msg={0}, value={1}", e.getMessage(), e.getStackTrace())); } |
●resフォルダのrawにある場合の割当例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Activity act = getActivity(); Context con = act.getApplicationContext(); MediaPlayer mp = new MediaPlayer(); //res\raw から音楽ファイルを得る String fileName = "android.resource://" + con.getPackageName() + "/" + R.raw.music ; try{ mp.setDataSource(con, Uri.parse(fileName)); } catch( IOException e){ //例外 throw new IllegalStateException( MessageFormat.format( "setDataSource error: msg={0}, value={1}", e.getMessage(), e.getStackTrace())); } |
音楽データの読み込み
void mp . prepareAsync ( ) ;
mp : MediaPlayer インスタンス
prepare は同期読み込み、prepareAsync は非同期読み込みです。両方共、音楽データの読み込みが完了すると Prepared 状態になります。
prepare は大きなサイズの音楽データを読み込むと、処理がブロックされるので注意してください。
prepareAsync は、読み込みが完了する前にプログラムに制御が戻ってきます。読み込み途中は Preparing 状態となります。
ただし、非同期読み込みの場合は読み込みが完了する前に、start や stop などの操作を行ってはいけません。非同期読み込みを利用するなら、リスナーを使って読み込みの完了を確認してから、start や stop などの操作を行って下さい。
読み込み完了通知を受け取るvoid mp . setOnPreparedListener ( MediaPlayer.OnPreparedListener listener ) ;
mp : MediaPlayer インスタンス
listener : 読み込み完了受信リスナー
非同期読み込みを開始する前に、読み込み完了リスナーを登録しておくと、音楽データの読み込みが完了した事がわかります。
OnPreparedListener を実装した専用のクラスを作成しても良いのですが、面倒くさいので無名クラスを用いても良いでしょう。
1 2 3 4 5 6 7 8 9 |
// mp は MediaPlayer のインスタンス変数 // 読み込み完了リスナー登録 mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { //読み込み完了で行いたい処理 } }); |
こんな感じです。
なおリスナーの登録は prepareAsync を行う前に設定する事を推奨します。
prepareAsync の後でリスナーを登録すると、極端に短い音楽データを読み込んだ場合、リスナーでイベントがキャッチできない(リスナーが動作する前に読み込みが終わる)ケースが考えられるためです。
また MediaPlayer はBGMや動画の再生などを目的としているため、極端に短い(試した範囲では 0.2秒以下の)音楽データを読み込むと、再生しても音が鳴らない事があります。
短い音(効果音)を鳴らすなら、SoundPool を使いましょう。
再生開始
mp : MediaPlayer インスタンス
再生を開始します。pause(再生中断)している場合は、中断した位置から再生を再開します。
演奏中は Started 状態になります。
boolean playing = mp . isPlaying () ;
mp : MediaPlayer インスタンス
listener : 再生完了受信リスナー
playing : 再生中ならTrue、それ以外はFalse
再生中か否かは isPlaying メソッドを使って判定可能です。
また演奏を開始する前に、再生完了リスナーを登録しておくと、音楽データの再生が完了した事がわかります。リスナーで再生完了を検知した場合は、状態が PlaybackCompleted になります。
OnCompletionListener を実装した専用のクラスを作成しても良いのですが、面倒くさいので無名クラスを用いても良いでしょう。
1 2 3 4 5 6 7 8 9 |
// mp は MediaPlayer のインスタンス変数 // 再生完了リスナー登録 mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { //再生完了で行いたい処理 } }); |
こんな感じです。
なおリスナーの登録は start を行う前に設定する事を推奨します。
再生位置を知る
曲の長さを得るint len = mp . getDuration();
mp : MediaPlayer インスタンス
len : 曲の長さ(ミリセカンド)
音楽データの長さをミリセカンド単位で知ることが可能です。
曲の長さは Prepared 、Started 、PlaybackCompleted 、Paused 、Stopped のいずれかの状態にある時だけ取得可能です。
曲の再生位置を得るint pos = mp . getCurrentPosition();
mp : MediaPlayer インスタンス
pos : 曲の再生位置(ミリセカンド)
音楽データの再生位置をミリセカンド単位で知ることが可能です。再生位置は曲の頭から見た再生時間になります。
曲の再生位置は Prepared 、Started 、PlaybackCompleted 、Paused 、Stopped のいずれかの状態にある時だけ取得可能です。
再生速度を変更する
再生速度を変更するPlaybackParams params = new PlaybackParams( ) ;
PlaybackParams p = params . setSpeed( float speed );
void mp . setPlaybackParams(PlaybackParams params );
mp : MediaPlayer インスタンス
params: パラメータインスタンス
speed : 再生速度(0.0f – 20.0f)
音楽データの再生速度を変更します。1.0 ならノーマル速度、0.5なら半分の速度、2.0なら倍速での再生になります。
speed に負の値や大きな値を与えると IllegalArgumentException 例外が発生するので注意してください。試した範囲では 20.0f 程度まではOKなようでした。
speed に 0.0 を与えた場合、pause (一時停止) したのと同意になります。
本命令は Android 6.0 (Marshmallow) 以降でサポートされた命令です。ターゲットOSが 6.0 以前 (Lollipop 以前)の場合は利用できません。
Lollipop 以前のOSでプログラムから再生速度を変更するには、なにやら難しい操作が必要なようで、少なくとも MediaPlayer では実現できないようです(汗)。
ボリュームを変更する
ボリュームを変更するvoid mp . setVolume ( float leftVolume, float rightVolume ) ;
mp : MediaPlayer インスタンス
leftVolume : 左音量(0.0 – 1.0)
rightVolume : 右音量(0.0 – 1.0)
左右独立で音量を変更します。1.0 が最大音量、0.0 が無音です。
MediaPlayer の音量は特に指定しない限り、システムのストリーム音量(メディア音量)に同調します。
ただし setVolume() メソッドで音量変更しても、システムのストリーム音量には影響を与えません。
つまりsetVolume() メソッドで音量を変更しても、該当MediaPlayerの音量のみが変更され、他のアプリケーションには影響が及ばないという事です。
またメディア音量以外のストリーム音量を変更しても、MediaPlayerのボリュームには影響しません。
再生中断
再生中断void mp . pause ();
mp : MediaPlayer インスタンス
再生を中断します。中断すると Paused 状態になります。
演奏を再開するには start メソッドを実行します。
再生終了
再生終了void mp . stop () ;
mp : MediaPlayer インスタンス
再生を終了します。終了すると Stopped 状態になります。
この状態から再度演奏を開始するには prepare または prepareAsync を実行し、曲データを読み直す必要があります。
初期化
初期化void mp . reset () ;
mp : MediaPlayer インスタンス
MediaPlayer オブジェクトを初期化します。初期化すると Idle 状態に戻ります。
本命令の使い所は、なにか問題が発生して最初からやりなおしたい場合と、ある曲が再生完了した後(あるいは再生途中)に、別の曲を再生したい場合となります。
その場合は、一度 reset して setDataSource からやり直す手順となります。
リソース開放
リソース開放void mp . release () ;
mp : MediaPlayer インスタンス
MediaPlayer オブジェクトを開放します。開放すると End 状態になります。
アプリケーションが onPause または onStop 状態になったら、release メソッドで資源を開放する事が推奨されています。
PROCESSINGの場合は、フラグメントの onDestroy をオーバライドして、release 処理を記述するのが良いでしょう。
開放されたオブジェクトは再利用できません。再度音楽を演奏するには、new または create から始める事になります。
【関連記事】
サンプルプログラム
シンプルな音楽再生例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
import android.app.Activity; import android.content.Context; import android.media.MediaPlayer; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import java.io.IOException; import java.text.MessageFormat; /** * Android Mode MediaPlayer Sample * @author MSLABO * @version 1.0 */ AssetManager assetManager; //Assetマネージャ AssetFileDescriptor fd = null; //Asset FD MediaPlayer player = null; //MediaPlayer Activity act; //Activity Context con; //コンテキスト /** * フラグメント停止時にリソースを開放する */ @Override public void onDestroy() { if( player != null ){ player.release(); } super.onDestroy(); } void setup() { fullScreen(); //変数の初期化や、各リソースの読み込みを行う act = getActivity(); con = act.getApplicationContext(); //MediaPlayerを生成する player = new MediaPlayer(); //アセットからBGMを読み込む assetManager = act.getResources().getAssets(); try{ //アセットをOPENします fd = assetManager.openFd("bgm01.ogg"); //音楽データを割り当てます player.setDataSource( fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); //同期読み込みを行います player.prepare(); //アセットを閉じます fd.close(); } catch( IOException e){ //例外 throw new IllegalStateException( MessageFormat.format( "music Preparation error: msg={0}, value={1}", e.getMessage(), e.getStackTrace())); } //テキスト表示の準備をする textFont(createFont("SansSerif", 30 * displayDensity)); textAlign(CENTER, CENTER); } public void draw() { background(200); fill(0); //曲の再生位置と長さを表示する if( player.isPlaying()){ //演奏中 text( "play" + "\n" + player.getCurrentPosition() + "/" + player.getDuration(),0, 0, width, height ); } else { //一時停止中 text( "pause" + "\n" + player.getCurrentPosition() + "/" + player.getDuration(),0, 0, width, height ); } } /** * タッチイベント */ public void touchStarted() { if( player.isPlaying()){ //再生中なら一時停止 player.pause(); } else { //それ以外なら再生 player.start(); } super.touchStarted(); } |
Dataフォルダの下にある「bgm01.ogg」を読み込んでいます。タップを行うと演奏を始めます。演奏中にタップすると一時停止します。
PROCESSINGの標準エディタでは R クラスを使ってリソースを読み込めないため、シンプルといいつつ、長いコーディングになっています(汗)。
下記にAndroidStudioで同じことを行うサンプルを掲載しておきます。
シンプルな音楽再生例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
import android.app.Activity; import android.content.Context; import android.media.MediaPlayer; import processing.core.PApplet; /** * Android Mode MediaPlayer Sample * @author MSLABO * @version 1.1 */ public class Sketch extends PApplet { MediaPlayer player = null; //MediaPlayer Activity act; //Activity Context con; //コンテキスト /** * フラグメント停止時にリソースを開放する */ @Override public void onDestroy() { if( player != null ){ player.release(); } super.onDestroy(); } @Override public void settings() { fullScreen(); } @Override public void setup() { act = getActivity(); con = act.getApplicationContext(); //MediaPlayerを生成する player = MediaPlayer.create( con, R.raw.bgm01 ); //テキスト表示の準備をする textFont(createFont("SansSerif", 30 * displayDensity)); textAlign(CENTER, CENTER); } @Override public void draw() { background(200); fill(0); //曲の再生位置と長さを表示する if( player.isPlaying()){ //演奏中 text( "play" + "\n" + player.getCurrentPosition() + "/" + player.getDuration(),0, 0, width, height ); } else { //一時停止中 text( "pause" + "\n" + player.getCurrentPosition() + "/" + player.getDuration(),0, 0, width, height ); } } /** * タッチイベント */ @Override public void touchStarted() { if( player.isPlaying()){ //再生中なら一時停止 player.pause(); } else { //それ以外なら再生 player.start(); } super.touchStarted(); } } |
上記例と同じことを行うプログラムを、AndroidStudioでコーディングしました。resフォルダの rawに「bgm01.ogg」という音楽データがある前提です。
MediaPlayer を new するのではなく create メソッドを使ってリソースフォルダの音楽データを読み込む事で、標準エディタの例に比べてシンプルにコーディングできていると思います。
ボリューム操作例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
import android.app.Activity; import android.content.Context; import android.media.MediaPlayer; import android.view.MotionEvent; import processing.core.PApplet; import processing.core.PFont; import processing.core.PImage; /** * PROCESSING AndroidMode MusicPlayer Sample * @author MSLABO * @version 1.2 */ public class Sketch extends PApplet { //列挙体:操作内容 enum eAction { Play, //再生 VolUp, //音量UP VolDown, //音量DOWN Non //操作なし } //ボタン管理簡易クラス class MyButton{ PImage img; int cx, cy; int ir; MyButton( String fileName, int xx, int yy ){ img = loadImage( fileName ); cx = xx + img.width/2; cy = yy + img.height/2; ir = img.width/2; } void Disp(){ imageMode( CENTER ); image( img, cx, cy ); imageMode( CORNERS ); } boolean isPush(float xx, float yy){ boolean ret = false; //ボタン押下されたか判定 if( dist( cx, cy, xx, yy ) < ir ){ ret = true; } return( ret ); } } final int BASE_FONT_SIZE = 32; Activity act; Context con; MediaPlayer player = null; MyButton playOnBtn, playOffBtn, volUpBtn, volDownBtn; float volume; eAction btnAction; PFont font; @Override public void settings() { fullScreen(); } /** * フラグメント表示直前にMediaPlayerを作成する */ @Override public void onResume() { //各リソース取得 act = getActivity(); con = act.getApplicationContext(); //MediaPlayer未作成なら生成 if( player == null ){ //プレーヤー生成 player = MediaPlayer.create(con,R.raw.battle); player.setLooping(true); //初期音量設定 volume = 0.5f; player.setVolume(volume, volume); } super.onResume(); } /** * フラグメント停止時にリソースを開放する */ @Override public void onDestroy() { //MediaPlayerを開放する if( player != null ){ player.release(); player = null; } super.onDestroy(); } @Override public void setup() { //各ボタンを作成する btnAction = eAction.Non; playOnBtn = new MyButton( "playOn.png", 412, 1010 ); playOffBtn = new MyButton( "playOff.png", 412, 1010 ); volUpBtn = new MyButton( "volUp.png", 786, 1054 ); volDownBtn = new MyButton( "volDown.png", 102, 1054 ); //文字表示設定 float fontSize = BASE_FONT_SIZE * displayDensity; font = createFont("ipag.ttf", fontSize); textSize(fontSize); textFont(font); textAlign(LEFT, TOP); } @Override public void draw() { background(200); //ボタンを表示する if( player.isPlaying()){ //再生中なら再生中ボタン画像表示 playOnBtn.Disp(); } else { //停止中なら再生停止中ボタン画像表示 playOffBtn.Disp(); } volUpBtn.Disp(); volDownBtn.Disp(); //操作内容に応じて処理実行 if( btnAction == eAction.Play) { //再生ボタン押下時 if (player.isPlaying()) { //いま再生中なら停止する player.pause(); } else { //いま停止中なら再生する player.start(); } btnAction = eAction.Non; } if( btnAction == eAction.VolUp){ //ボリュームUPボタン押下時 volume = volume + 0.05f; if( volume > 1.0f ){ volume = 1.0f; } player.setVolume(volume, volume); btnAction = eAction.Non; } if( btnAction == eAction.VolDown){ //ボリュームDOWNボタン押下時 volume = volume - 0.05f; if( volume < 0.0f ){ volume = 0.0f; } player.setVolume(volume, volume); btnAction = eAction.Non; } //再生位置とボリュームを表示 fill(0); text( nf( player.getCurrentPosition(), 7) + "/" + nf( player.getDuration(), 7) , 200, 380 ); text( volume, 360, 500 ); } @Override public boolean surfaceTouchEvent(MotionEvent motionEvent) { int Action = motionEvent.getActionMasked(); int pIndex = motionEvent.getActionIndex(); float ax = motionEvent.getX( pIndex ); float ay = motionEvent.getY( pIndex ); //どのボタンが押されたかを判定する if( Action == MotionEvent.ACTION_DOWN ){ if( playOnBtn.isPush(ax,ay) ){ btnAction = eAction.Play; } if( volUpBtn.isPush(ax,ay)){ btnAction = eAction.VolUp; } if( volDownBtn.isPush(ax,ay)){ btnAction = eAction.VolDown; } } return super.surfaceTouchEvent(motionEvent); } } |
ボリュームの操作機能付きの超超簡易音楽プレーヤー例です。
画面に表示されるスピーカーの絵のボタンを押下すると、音量が変更可能です。
<出力サンプル>
(画像URL:illust-AC 様:yamaboshiさん)
下記はサンプルプログラムと同じ動きになるように、 P5.js で書き直したものです。動作イメージを確認できます。※細かい動作や表示が少しだけ異なりますが・・・そこはご愛嬌で・・(汗)。
音楽ファイルは wingless-seraph 様からお借りしました。かっこいいBGMです。
なお一部のスマホ搭載ブラウザからは正しく表示されない場合があります。その場合はPCから閲覧してください。
(画像URL:illust-AC 様:yamaboshiさん、効果音:wingless-seraph 様)
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。