【Unity】【C#】動的にオーディオファイルの読み込みと再生をする 
2018/07/04 Wed [edit]
プラグイン ver.1.16 の簡易音楽プレイヤーを作る際にちょっと調べたんだけど、VideoPlayer と違って、基本的に WWW を使うのが常套みたいだね。プラグインのデモスクリプトとしては「EasyMusicPlayer.cs」と「ExternalStorageTest2.cs」の2種類で書かれているが、基本は同じなので再利用しやすい部分を抜粋して書いておくことにした。実際に使う際にはもう少し手を加えた方が便利かも知れない。
|
(※) Unity 5.6.3p1 - 2018.1.8f1 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認
■オーディオファイルの読み込みと再生のコード
●オーディオファイルの読み込みと再生
using System.Collections;
using System.IO;
using UnityEngine;
public class AudioLoadTest : MonoBehaviour //※クラス名は任意
{
public AudioSource audioSource; //インスペクタで AudioSource をセット
public string path = "/storage/emulated/0/Music/sample.mp3"; //※ファイルは任意
//外部からの呼び出し用メソッド
public void LoadAudio(string path)
{
if (Path.GetExtension(path) == ".m4a") //※"m4a"は再生できないっぽい
{
Debug.Log("Not supported audio format.");
return;
}
StartCoroutine(LoadToAudioClipAndPlay(path));
}
//ファイルの読み込み(ダウンロード)と再生
IEnumerator LoadToAudioClipAndPlay(string path)
{
if (audioSource == null || string.IsNullOrEmpty(path))
yield break;
if (!File.Exists(path)) {
//ここにファイルが見つからない処理
Debug.Log("File not found.");
yield break;
}
using(WWW www = new WWW("file://" + path)) //※あくまでローカルファイルとする
{
while (!www.isDone)
yield return null;
AudioClip audioClip = www.GetAudioClip(false, true);
if (audioClip.loadState != AudioDataLoadState.Loaded)
{
//ここにロード失敗処理
Debug.Log("Failed to load AudioClip.");
yield break;
}
//ここにロード成功処理
audioSource.clip = audioClip;
audioSource.Play();
Debug.Log("Load success : " + path);
}
}
// Use this for initialization
private void Start () {
//起動時に読み込むときなど
LoadAudio(path); //※メインからの呼び出し例
}
}
ここではインスペクタに path を入力し読み込むようになっているが、外部呼び出し用のメソッド「LoadAudio()」の引数にパスを渡すようになっているので、通常は「Start()」内の呼び出しは削除した方が良いだろう(ただのメインからの呼び出し例のため)。
オーディオファイルの読み込みには WWW を使っているが、あくまでローカルストレージを想定しているので、頭に "file://" を付けているのに注意して欲しい。インターネットからダウンロードしたい場合は "file://" を取り除いて URL形式("http://~")を直接与えれば良いと思う。しかしその場合、タイムアウトを付けたり、キャッシュ付きなどを使う必要があるかも知れない(パケ代もかかるので)。
WWW を使っている分にはオーディオ形式は気にしなくても良いが、再生するには "mp3" や "ogg", "wav" などが良いようだ。"m4a" は読み込み(ダウンロード)はできるが、再生はできなかった(Unity2018.1.5f1時点。Windows はエディタのみ。ランタイムは以下を参照)。
・Windows で mp3 をランタイムで再生する
スマホで使うにはアクセス権などが必要になることもあるが、とりあえずはこれだけで読み込みと再生はできる。以降では更にプラグインを利用して、自由にファイルを選択して読み込む方法もやってみよう。
・Android アプリでパーミッション(権限)要求をする
■スマホ(Android)のストレージから読み込んで再生する
ここではプラグインを使ってストレージを開き、再生する方法を書いておこう。といってもスクリプト自体は上記の例そのままで良いので、後はプレファブをシーンに置き、コールバックをセットするだけだ。プラグインのインストールからはじめる場合は、以前の記事を参考にして欲しい。
1.先に作った「AudioLoadTest.cs」スクリプトを適当な GameObjectにアタッチし、「AudioSource」を追加し、インスペクタでセットドラッグ&ドロップでセットしよう。「Play On Awake」はオフに、「Loop」はオンにしておくと良い(※曲を繰り返し再生する場合)。

2.シーンにプレファブ「StorageOpenAudioController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと楽)を置き、インスペクタで「Mime Types」に読み込むオーディオ形式の MIME type を入れておく。ここでは mp3/m4a = "audio/mpeg", ogg = "audio/ogg","application/ogg" を入れているが、任意で良い(※デフォルト=空の状態ではすべてのオーディオ形式となる)。


なお、ogg の MIME type が2種類書かれているが、プロバイダ(ストレージ)の種類によって、同じ拡張子でも MIME type が違ってたりするので注意が必要だ。例えばローカルストレージでは "application/ogg" となり、GoogleDrive などでは "audio/ogg" で認識される。今回の再生の場合、ローカルストレージの "application/ogg" だけでも良い(複数指定して置けば、どのプロバイダ[ストレージ]でも見えるようになる)。直接開けるか否かはアプリの対応状況によるため、実際に使う際にはあらかじめ絞り込んでおくのも良いだろう。
※ここで言う「プロバイダ」とはアプリが持つ情報提供プログラムのことである。Android アプリはそれぞれアプリごとにプロバイダを持つことができ、それによりユーザーに与える情報を制限することができる。この例の場合、ローカルストレージや GoogleDrive(これは1つのアプリである)、OneDrive(これもアプリ)ごとということになるので、「ストレージ」ごとになることと同義になる。
3.シーンにロード用のボタンを置き、コールバック「OnClick」に「StorageOpenAudioController.Show」を登録する。これでボタンを押すことにより、ストレージが開く。


4.プレファブ「StorageOpenAudioController」に戻り、「OnResult」に先に作ったスクリプト「AudioLoadTest.LoadAudio」を登録する(※手順2の画像のようになる)。これでストレージから選択したオーディオファイルのパスがスクリプトに渡され、読み込みが成功すれば再生される(※"m4a" は再生できないようなので(Unity2018.1.5f1 時点)、LoadAudio() で拡張子チェックをしてるが、実際に使うには拡張子で絞るようにしても良い。「EasyMusicPlayer.cs」(~/FantomLib/Scripts/Example/ 以下)にはその例も書かれているので必要なら参照)。なお、GoogleDrive などクラウドストレージからは直接再生(情報取得)できないので注意。その場合は一旦ローカルストレージにコピー(ダウンロード)すれば再生できるようになる。これで読み込みと再生だけなら完成だ。

※実機でログを確認するにはシーンに「DebugConsole」(~/FantomLib/Prefabs/System/ 以下)を置き、「AudioLoadTest.cs」内の「Debug.Log()」→「XDebug.Log()」にしておく。ビルドするには「デモのビルド」と基本的に同じ(シーンだけ変える)なので必要なら参照。
あとは「プレイ/停止」など操作できるとなお良いね。このあたりのサンプルはデモシーン「ExternalStorageTest」の「ExternalStorageTest2.cs」に、またはシーン「MusicPlayerExample」の「EasyMusicPlayer.cs」(~/FantomLib/Scripts/Example/ 以下)に書かれているので、コピペしても良いと思う。「EasyMusicPlayer.cs」には連続再生やシャッフル、次の曲/前の曲、プレイリストに追加/削除など、一般的な操作の例を入れてあるので、必要なら参照して欲しい(最低限の機能で良いなら、そのまま使っても良い→「UnityChanInOtakuCity」はそのまま使ってる)。
|
※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。
(関連記事)
【Unity】【C#】Windows で mp3 をランタイムで再生する
【Unity】【C#】オーディオ再生でのエラー:An invalid seek position was passed to this function の対処法
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】【C#】VideoPlayer で動画の終了判定をする

- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/299-c20b280e
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |