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;
}
}
点击这里下载项目文件