視線で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();
    }

 


}