視線でmp3もwavも再生できるようにする③ 出来たけどそのうち整理したい
最初に出てきた「mp3」ファイルを演奏するように変えてみます。
今は
mp3Path = Pathmei[1];
という感じに、指定した要素の番号をmp3Pathに入れて、鳴らしています。
これを変えるには、
mp3が出たら、for文から抜けて、そのときの「i」を
mp3Path = Pathmei[i];
という風に入れたらいいはず。
これは下記で出来ましたが、前の記事と少し変えたところがあります。
for(i = 0; i < 4;)
{
Debug.Log(Pathmei[i]);
string file = Pathmei[i];
//拡張子の出力
Debug.Log(Path.GetExtension(file));
//ファイル名の出力
Debug.Log(Path.GetFileNameWithoutExtension(file));
if (Path.GetExtension(file).Contains("mp3"))
{
Debug.Log($"mp3あったよ:{i}");
break;
}
else if (Path.GetExtension(file).Contains("wav"))
{
Debug.Log($"wavあったよ:{i}");
}
else
{
Debug.Log($"どっちもないよ:{i}");
}
i++;
}
mp3Path = Pathmei[i];
Debug.Log(Pathmei[i]);
前は
for(int i = 0; i < 4;)
でしたが、for文から抜けると、i が使えなくなってしまったので、
for文に入る前に
int = 1;
と宣言しておきました。
これで問題なく、最初にみつけたmp3を鳴らせました。
それでは、wavしかなかったときにはwavを鳴らすプログラムを書いていきます。
・・・
完成しました。
が、決してmp3優先ではないです。
wavが先に鳴ることもあります。
ファイルの名前の順のようです。
英語→日本語の順。
まあ、これはあんまり気になりませんので、必要なときがきたら直します。
全部貼り付けます。
余計なコードも入ってると思いますが、今のところ消してエラーが出ても
対応できないのでこのままいきます。
usingがすごく多いです。 これ全部いるのか不明です。
そのうち、整理します。
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using Tobii.Gaming; //ライブラリの追加
using NAudio.Wave; //← 見つからないとエラーが出たときは Import Settings を見直す
public class play : MonoBehaviour
{
public AudioSource audioSource;
//public string mp3Path; //再生する mp3 のパス。ここに書いたstring はInspectorで触れるようになる
string mp3Path = "C:/sound"; //今までは↑の行で、InspectorのAudio Sourceにパスを指定していたが、ファイルの拡張子を判断したいのでこっちに変えた
//注視情報
private GazeAware gazeAware;
//停止中か再生中かなど
int ichiziteishi;
//配列の番号
int i = 0;
private void Start()
{
//audioSource = this.GetComponent<AudioSource>();
//StartCoroutine(Connect());
//注視情報の取得
gazeAware = GetComponent<GazeAware>();
//一時停止が押されたかどうかを見るための変数。最初と再生中は1.一時停止中は2
ichiziteishi = 1;
string[] Pathmei = System.IO.Directory.GetFiles(mp3Path, "*", System.IO.SearchOption.AllDirectories);
for (i = 0; i < 4;)
{
Debug.Log(Pathmei[i]);
string file = Pathmei[i];
//拡張子の出力
Debug.Log(Path.GetExtension(file));
//ファイル名の出力
Debug.Log(Path.GetFileNameWithoutExtension(file));
if (Path.GetExtension(file).Contains("mp3"))
{
Debug.Log($"mp3あったよ:{i}");
mp3Path = Pathmei[i];
break;
}
else if (Path.GetExtension(file).Contains("wav"))
{
Debug.Log($"wavあったよ:{i}");
var wavPath = Pathmei[i]; // Application.temporaryCachePath内にconverted.wavという名前で保存
Debug.Log($"wav鳴らせるかな:{i}");
StartCoroutine(PlayWav(wavPath));
break;
}
else
{
Debug.Log($"どっちもないよ:{i}");
}
i++;
}
if (File.Exists(mp3Path)) //Fileが存在しているか。もししているなら。
{
//wav 変換した一時ファイルを保存するパス
var wavPath = Application.temporaryCachePath + "/converted.wav"; // Application.temporaryCachePath内にconverted.wavという名前で保存
Mp3ToWAV(mp3Path, wavPath);
StartCoroutine(PlayWav(wavPath));
}
else
{
Debug.Log($"File not found : {mp3Path}");
}
}
//mp3 → wav 変換して、保存したパスを返す
public void Mp3ToWAV(string mp3Path, string wavPath)
{
//ファイルを byte 配列で読み込み
var bytes = File.ReadAllBytes(mp3Path); //File.ReadAllBytes:バイナリ ファイルを開き、ファイルの内容をバイト配列に読み取った後、ファイルを閉じます。
//wav を一時ファイルとして保存
using (var stream = new MemoryStream()) //MemoryStreamはFileには保存しないが、メモリにデータを読み書きするクラス
{
stream.Write(bytes, 0, bytes.Length); //stream.Write で書き込み。bytes.Lengthで、bytesの配列全体を書き込み。
stream.Position = 0; //ストリームの位置を先頭に。ここに10と入れたら10バイト目にセットすることになる。
using (var reader = new Mp3FileReader(stream)) //Mp3FileReader:mp3Fileから読み込む Mp3FileReader(stream) でstreamのmp3Fileを読む。だと思う。
{
WaveFileWriter.CreateWaveFile(wavPath, reader); //wav で書き出し(mp3なら「MediaFoundationEncoder」wavなら「WaveFileWriter」)
Debug.Log($"Convert to wav successfully : {wavPath}"); //うまく行ったらwav保存先のパスを表示
}
}
}
void Update()
{
// マウスの左ボタンを推した場合も再生
//オブジェクトを注視していたらTrue
bool flg = gazeAware.HasGazeFocus;
//注視していたり、マウスが左クリックされたら
if (flg || Input.GetMouseButtonDown(0))
{
//注視していたら赤色に
gameObject.GetComponent<Renderer>().material.color = Color.red;
if (!audioSource.isPlaying) //再生中で無いなら
{
//一時停止関数がもし2(一時停止中)なら
if (ichiziteishi == 2)
{
//再開してください(同時にichiziteisi変数は1になる)
UnPause();
}
//一時停止関数がもし1(一時停止中でない(起動したところだったり、停止中だったり))なら再生する。
else
{
audioSource.Play();
// Play(audioClip);
}
}
}
//注視して無かったり、マウス左クリックされてなかったりしたら
else
{
//注視していなければ青色に
gameObject.GetComponent<Renderer>().material.color = Color.blue;
//注視がそれただけでは一時停止にはしていない。視線がそれることはよくあると思うので。
//一時停止にしたいならPauseを入れたら可能。
//改訂として目をそらしたら止めるようにする
// Pause();
}
// 停止
if (audioSource.isPlaying) //再生中なら
{
//注視がそれているときのみ有効。テンキーの「2」を押して離したら停止
if (Input.GetKeyUp(KeyCode.Keypad2))
{
Stop();
}
}
// 注視がそれているときのみ有効。一時停止
if (audioSource.isPlaying) //再生中なら
{
//テンキーの「1」を押して離したら一時停止し、ichiziteishi変数を2に。
if (Input.GetKeyUp(KeyCode.Keypad1))
{
Pause();
}
}
// 再開
if (!audioSource.isPlaying) //停止中なら
{
//もう一回、注視したり左クリックしたりしたら再開し、ichiziteishi変数を1に。
if (flg || Input.GetMouseButtonDown(0))
{
UnPause();
}
}
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
//ストリーミング再生する
IEnumerator PlayWav(string path) //IEnumeratorはコルーチンを使うのに宣言するとき使う。PlayWavは関数名。
//コルーチンは好きな場所で処理を止めたり再開したりできる機能
{
using (var www = new WWW("file://" + path)) //www(url)でURLにアクセスする
{
while (!www.isDone) //while(条件式) 条件式が真である限りループする。www.isDoneはダウンロード終了したかどうかを読み取る。!がついているから「終了していない限り処理する」ということ。と思う。
yield return null; //1フレーム停止
if (string.IsNullOrEmpty(www.error)) //string.IsNullOrEmptyは指定の文字列が、nullもしくは空の文字列かを判断
//www.errorはダウンロード中にエラーが起きたときのメッセージ
{
var clip = www.GetAudioClip(false, true); //最初のはクリップを2Dにする(false)3Dは(true)だと思う。よく分かってない。後の真偽はtrueならダウンロード中も再生。falseならダウンロードしてから再生
audioSource.clip = clip;
//audioSource.Play();
Debug.Log($"Play wav : {path}");
}
else
{
Debug.Log(www.error);
}
}
}
//再生、一時停止、停止、再開、完全に停止について
/*
// 再生 Play と、入力したら一回だけ再生
private void Play(AudioClip audi)
{
audioSource.PlayOneShot(audi);
}
*/
// 一時停止 Pauseと、入力したらichiziteishi変数に2を入れて、一時停止
private void Pause()
{
ichiziteishi = 2;
audioSource.Pause();
}
// 停止 Stopと、入力したら停止
private void Stop()
{
audioSource.Stop();
}
// 再開 UnPause と、入力したらichiziteishi変数に1を入れて、再開
private void UnPause()
{
ichiziteishi = 1;
audioSource.UnPause();
}
}