.NET MAUI播放音頻文件,複製資源文件到安裝目錄。

.NET MAUI我基本都是參考Android代碼改造來的,官方文檔 = 廢品。
參考:https://blog.csdn.net/wxzjn1027/article/details/82345604
需要注意的是,流的加載過程是一個將音頻解壓爲原始16位PCM數據的過程,由一個後臺線程來進行處理異步,所以初始化後不能立即播放,需要等待一點時間。

有以下幾個函數可用於控制播放:
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
播放指定音頻的音效,並返回一個streamID 。
priority —— 流的優先級,值越大優先級高,影響當同時播放數量超出了最大支持數時SoundPool對該流的處理;
loop —— 循環播放的次數,0爲值播放一次,-1爲無限循環,其他值爲播放loop+1次(例如,3爲一共播放4次).
rate —— 播放的速率,範圍0.5-2.0(0.5爲一半速率,1.0爲正常速率,2.0爲兩倍速率)
final void pause(int streamID)
暫停指定播放流的音效(streamID 應通過play()返回)。
final void resume(int streamID)
繼續播放指定播放流的音效(streamID 應通過play()返回)。
final void stop(int streamID)
終止指定播放流的音效(streamID 應通過play()返回)。

這裏需要注意的是,
1.play()函數傳遞的是一個load()返回的soundID——指向一個被記載的音頻資源 ,如果播放成功則返回一個非0的streamID——指向一個成功播放的流 ;同一個soundID 可以通過多次調用play()而獲得多個不同的streamID (只要不超出同時播放的最大數量);
2.pause()、resume()和stop()是針對播放流操作的,傳遞的是play()返回的streamID ;
3.play()中的priority參數,只在同時播放的流的數量超過了預先設定的最大數量時起作用,管理器將自動終止優先級低的播放流。如果存在多個同樣優先級的流,再進一步根據其創建時間來處理,新創建的流的年齡是最小的,將被終止;
4.無論如何,程序退出時,手動終止播放並釋放資源是必要的。

using Android.Annotation;
using Android.Media;using Stream = Android.Media.Stream;

namespace NetAppTest.Utils
{
    public class PlaySoundUtil : IDisposable
    {
        //音頻池
        public static SoundPool soundPool = null;
        //預加載的音頻文件
        public static Dictionary<int, int> mSoundCtrl = new Dictionary<int, int>();

        /// <summary>
        /// 加載音頻文件
        /// </summary>
        /// <param name="soundId">自定義音頻資源id</param>
        /// <param name="rawPath">音頻資源名(1.mp3)</param>
        /// <exception cref="System.Exception"></exception>
        public static void LoadSoundResource(int soundId, string rawPath)
        {
            //已經加載過,返回。
            if (mSoundCtrl.ContainsKey(soundId))
            {
                return;
            }
            //初始化音頻資源池
            if (soundPool == null)
            {
                //音頻資源池建造者
                SoundPool.Builder builder = new SoundPool.Builder();
                //同時播放的流的最大數量
                builder.SetMaxStreams(1);
                //AudioAttributes是一個封裝音頻各種屬性的方法
                AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
                //設置音頻流的合適的屬性
                attrBuilder.SetLegacyStreamType(Stream.Music);
                //加載一個AudioAttributes
                builder.SetAudioAttributes(attrBuilder.Build());
                //建造對象
                soundPool = builder.Build();
            }
            //拼接完整音頻文件路徑,需要先把音頻文件copy到這個目錄中
            string targetFile = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, rawPath);
            //加載進音頻資源池,返回一個非0的音頻id。
            int ret = soundPool.Load(targetFile, 1);
            if (ret < 1)
            {
                throw new System.Exception("裝載聲音資源時發生異常:ID=" + soundId);
            }
            //保存進字典變量
            mSoundCtrl.Add(soundId, ret);
        }

        /// <summary>
        /// 初始化音頻資源
        /// </summary>
        public static void loadData()
        {
            try
            {
                string path1 = "1.mp3";
                LoadSoundResource(1, path1);
            }
            catch (System.Exception ex)
            {
                
            }
        }

        /// <summary>
        /// 播放音頻資源
        /// </summary>
        /// <param name="soundId">資源id</param>
        public static void play(int soundId)
        {
            try
            {
                if (!mSoundCtrl.ContainsKey(soundId))
                {return;
                }
                //獲取、播放音頻
                int r = mSoundCtrl[soundId];
                int ret = soundPool.Play(r, 1.0f, 1.0f, 0, 0, 1);
                if (ret < 1)
                {return;
                }
            }
            catch (System.Exception ex)
            {
                
            }
        }

        /// <summary>
        /// 釋放資源
        /// </summary>
        public void Dispose()
        {
            if (soundPool == null)
            {
                return;
            }
            soundPool.Release();
        }
    }
}

 複製到新目錄中

        public async static void CopyConfigFile()
        {
            //1.mp3存放於/Resources/Raw/
            string fileName1 = "1.mp3";
            string fileTargetPath1 = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, fileName1);
            if (File.Exists(fileTargetPath1))
            {
                File.Delete(fileTargetPath1);
            }
            bool v1 = await FileSystem.Current.AppPackageFileExistsAsync(fileName1);
            if (v1)
            {
                using System.IO.Stream fileStream = await FileSystem.Current.OpenAppPackageFileAsync(fileName1);
                // 緩衝區爲10k
                byte[] buffer = new Byte[10000];

                // 文件長度
                int length;
                using System.IO.FileStream fs = new System.IO.FileStream(fileTargetPath1, FileMode.OpenOrCreate);
                do
                {
                    length = fileStream.Read(buffer, 0, 10000);
                    fs.Write(buffer, 0, length);
                    buffer = new Byte[10000];
                } while (length > 0);
                fs.Flush();
            }
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章