unity3d 直接播放mp3 显示封面
using UnityEngine; using System.Collections; using Id3Lib; using NAudio.Wave; using System.IO; using System; using System.Text; using System.Runtime.InteropServices; public class MusicPlayer : MonoBehaviour { private IWavePlayer iwavePlayer; private WaveStream waveStream; private WaveChannel32 waveChannel32; Texture2D t; string path=""; // Use this for initialization void Start() { } void LoadMusic(string path) { byte[] imageData; using (FileStream fsRead = new FileStream(path, FileMode.Open)) { int fsLen = (int)fsRead.Length; imageData = new byte[fsLen]; fsRead.Read(imageData, 0, imageData.Length); } LoadAudioFromData(imageData); t = GetAlbumCover(path); } private bool LoadAudioFromData(byte[] data) { try { MemoryStream tmpStr = new MemoryStream(data); waveStream = new Mp3FileReader(tmpStr); waveChannel32 = new WaveChannel32(waveStream); iwavePlayer = new WaveOut(); iwavePlayer.Init(waveChannel32); return true; } catch (System.Exception ex) { Debug.LogWarning("Error! " + ex.Message); } return false; } // Update is called once per frame void Update() { } void OnGUI() { if (GUI.Button(new Rect(0, 0, 120, 30), "选择音乐")) { OpenFileName ofn = new OpenFileName(); ofn.structSize = Marshal.SizeOf(ofn); ofn.filter = "mp3(*.mp3)\0*.mp3"; ofn.file = new string(new char[256]); ofn.maxFile = ofn.file.Length; ofn.fileTitle = new string(new char[64]); ofn.maxFileTitle = ofn.fileTitle.Length; ofn.initialDir = UnityEngine.Application.dataPath;//默认路径 ofn.title = "选择音乐"; ofn.defExt = "mp3";//显示文件的类型 //注意 一下项目不一定要全选 但是0x00000008项不要缺少 ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR if (WindowDll.GetOpenFileName(ofn)) { Debug.Log("Selected file with full path: {0}" + ofn.file); LoadMusic(ofn.file); path = ofn.file; } ofn = null; Resources.UnloadUnusedAssets(); } if(GUI.Button(new Rect(0,30,120,30),"播放")) { iwavePlayer.Play(); } if (GUI.Button(new Rect(0, 60, 120, 30), "暂停")) { iwavePlayer.Pause(); } if (GUI.Button(new Rect(0, 90, 120, 30), "停止")) { iwavePlayer.Stop(); } GUI.Label(new Rect(200, 170, 500, 30), path); if(t!=null) { GUI.DrawTexture(new Rect(200, 200, 200, 200), t); } } void OnApplicationQuit() { if (iwavePlayer!=null) { iwavePlayer.Dispose(); } } /// <summary> /// 获取音乐封面 /// </summary> /// <param name="path"></param> /// <returns></returns> public Texture2D GetAlbumCover(string path) { Texture2D image = null; FileStream fs = new FileStream(path, FileMode.Open); try { byte[] header = new byte[10]; //标签头 int offset = 0; bool haveAPIC = false; fs.Read(header, 0, 10); offset += 10; string head = Encoding.Default.GetString(header, 0, 3); if (head.Equals("ID3")) { int sizeAll = header[6] * 0x200000 //获取该标签的尺寸,不包括标签头 + header[7] * 0x4000 + header[8] * 0x80 + header[9]; int size = 0; byte[] body = new byte[10]; //数据帧头,这里认为数据帧头不包括编码方式 fs.Read(body, 0, 10); offset += 10; head = Encoding.Default.GetString(body, 0, 4); while (offset < sizeAll) //当数据帧不是图片的时候继续查找 { if (("APIC".Equals(head))) { haveAPIC = true; break; } size = body[size + 4] * 0x1000000 //获取该数据帧的尺寸(不包括帧头) + body[size + 5] * 0x10000 + body[size + 6] * 0x100 + body[size + 7]; body = new byte[size + 10]; fs.Read(body, 0, size + 10); offset += size + 10; head = Encoding.Default.GetString(body, size, 4); } if (haveAPIC) { size = body[size + 4] * 0x1000000 + body[size + 5] * 0x10000 + body[size + 6] * 0x100 + body[size + 7]; byte[] temp = new byte[9]; byte[] temptype = new byte[10]; fs.Seek(1, SeekOrigin.Current); fs.Read(temp, 0, 9); int i = 0; switch (Encoding.Default.GetString(temp)) { case "image/jpe": while (i < size) //jpeg开头0xFFD8 { if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216) { break; } fs.Seek(-2, SeekOrigin.Current); fs.Read(temptype, 0, 3); i++; } fs.Seek(-2, SeekOrigin.Current); break; case "image/jpg": while (i < size) //jpg开头0xFFD8 { if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216) { break; } fs.Seek(-2, SeekOrigin.Current); fs.Read(temptype, 0, 3); i++; } fs.Seek(-2, SeekOrigin.Current); break; case "image/gif": while (i < size) //gif开头474946 { if (temptype[0] == 71 && temptype[1] == 73 && temptype[2] == 70) { break; } fs.Seek(-2, SeekOrigin.Current); fs.Read(temptype, 0, 3); i++; } fs.Seek(-3, SeekOrigin.Current); break; case "image/bmp": while (i < size) //bmp开头424d { if (temptype[0] == 66 && temptype[1] == 77) { break; } fs.Seek(-1, SeekOrigin.Current); fs.Read(temptype, 0, 2); i++; } fs.Seek(-2, SeekOrigin.Current); break; case "image/png": while (i < size) //png开头89 50 4e 47 0d 0a 1a 0a { if (temptype[0] == 137 && temptype[1] == 80 && temptype[2] == 78 && temptype[3] == 71 && temptype[4] == 13) { break; } fs.Seek(-9, SeekOrigin.Current); fs.Read(temptype, 0, 10); i++; } fs.Seek(-10, SeekOrigin.Current); break; default://FFFB为音频的开头 break; } byte[] imageBytes = new byte[size]; fs.Read(imageBytes, 0, size); image = new Texture2D(128, 128); image.LoadImage(imageBytes); } else { image = null; } } else { image = null; } } catch (Exception ex) { Debug.LogWarning(ex.Message); } finally { fs.Close(); } return image; } }
点击这里下载项目文件