質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

2661閲覧

Unityでのアプリ外保存Mp3再生方法

yuya382

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/07/29 13:33

前提・実現したいこと

UnityでApplication.persistentDataPathに置いたMP3ファイルを読み込み、再生したいと思っています。
AssetStoreのプラグインは使わずにAudioClipにMP3ファイルをロード、再生する方法はないのでしょうか?

音声ファイルはMP3のみで対応しなくてはいけません。
ご回答、ご教授お願いいたします。

発生している問題・エラーメッセージ

Streaming of 'mpeg' on this platform is not supported UnityEngine.WWW:GetAudioClip(Boolean, Boolean) <LoadAudioFile>d__25:MoveNext() (at Assets/Scripts/Scene/script:198) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

該当のソースコード

c#

1 2 3 IEnumerator LoadAudioFile( AudioClip sentenceAudioClip,string path) 4 { 5 if (audioSource == null || string.IsNullOrEmpty(path)) 6 yield break; 7 8 if (!File.Exists(path)) 9 { 10 //ここにファイルが見つからない処理 11 Debug.Log("File not found."); 12 yield break; 13 } 14 15 using (WWW www = new WWW("file://" + path)) //※あくまでローカルファイルとする 16 { 17 while (!www.isDone) 18 yield return null; 19 20 AudioClip audioClip = www.GetAudioClip(false, true); 21 if (audioClip.loadState != AudioDataLoadState.Loaded) 22 { 23 //ここにロード失敗処理 24 Debug.Log("Failed to load AudioClip."); 25 yield break; 26 } 27 28 //ここにロード成功処理 29 sentenceAudioClip = audioClip; 30 Debug.Log("Load success : " + path); 31 } 32 } 33 34

試したこと

https://github.com/r2123b/Load-Mp3-into-Audioclip
これで音声は再生できたのですが、音質が酷くわるくなり使い物になりませんでした

補足情報(FW/ツールのバージョンなど)

Unity Version;2019.1.5f

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

音質がひどいとなると、デコードのスピードが再生に間に合っていないのかもしれませんね...

ローカルのファイルということでしたら、ストリーミング再生でなくてもさほど問題ないでしょうか?
もしそうであれば、MP3データを再生前にすべてデコードしてしまって、生の波形データをオーディオクリップにセットするというのはどうでしょう。
ご提示の参考サイトと同様にNLayerを使って...

C#

1using System.Collections; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using NLayer; 6using UnityEngine; 7using UnityEngine.Networking; 8 9// 中略 10 11// ご提示のコードにある「sentenceAudioClip」というのは、何のためのものかよく分からなかったため省略しています 12// 代わりに、できあがったオーディオクリップはaudioSource.clipにセットしました 13IEnumerator LoadAudioFile(string path) 14{ 15 if (audioSource == null || string.IsNullOrEmpty(path)) 16 yield break; 17 18 if (!File.Exists(path)) 19 { 20 //ここにファイルが見つからない処理 21 Debug.Log("File not found."); 22 yield break; 23 } 24 25 // データ自体はオーディオデータとしてではなく一般データとして読み込み... 26 using (var request = UnityWebRequest.Get("file://" + path)) //※あくまでローカルファイルとする 27 { 28 yield return request.SendWebRequest(); 29 30 if (request.isHttpError || request.isNetworkError) 31 { 32 //ここにロード失敗処理 33 Debug.Log($"Failed to load AudioClip. {request.error}"); 34 yield break; 35 } 36 37 //ここにロード成功処理 38 // 得られたMP3データをすべてPCMデータにデコードしてしまい、それをオーディオクリップにセットする 39 var mp3Data = request.downloadHandler.data; 40 using (var mp3Stream = new MemoryStream(mp3Data)) 41 { 42 var mpegFile = new MpegFile(mp3Stream); 43 var size = mpegFile.Length; 44 var channels = mpegFile.Channels; 45 var sampleRate = mpegFile.SampleRate; 46 47 Debug.Log($"PCM size : {size / (1024.0 * 1024.0):F2} MiB"); 48 Debug.Log($"Channels : {channels}"); 49 Debug.Log($"Duration : {mpegFile.Duration}"); 50 Debug.Log($"Sample rate : {sampleRate}"); 51 52 var totalSampleCount = (int)(size / sizeof(float)); 53 var decodedSamples = new List<float>(totalSampleCount); 54 var buffer = new float[sampleRate]; 55 var sampleOffset = 0; 56 const int yieldInterval = 10; 57 var yieldCount = 0; 58 do 59 { 60 var decodedSampleCount = mpegFile.ReadSamples(buffer, 0, sampleRate); 61 decodedSamples.AddRange(buffer.Take(decodedSampleCount)); 62 sampleOffset += decodedSampleCount; 63 yieldCount++; 64 if ((yieldCount % yieldInterval) > 0) 65 { 66 continue; 67 } 68 69 Debug.Log($"Please wait... ({sampleOffset} / {totalSampleCount})"); 70 yield return null; 71 } while (sampleOffset < totalSampleCount); 72 73 var audioClip = AudioClip.Create("Audio", totalSampleCount / channels, channels, sampleRate, false); 74 audioClip.SetData(decodedSamples.ToArray(), 0); 75 audioSource.clip = audioClip; 76 } 77 Debug.Log("Load success : " + path); 78 } 79}

としてみるとどうでしょうか。
曲が長いとメモリ消費量が大きくなってしまいますが、その場合はデータをOgg Vorbisにエンコードするとかの方法を探す必要がありそうです...

投稿2020/08/01 01:06

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問