using System.Collections;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
[HideInInspector]
[CustomEditor(typeof(PlayMusic))]
public class PlayMusicEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
PlayMusic playMusic = (PlayMusic)target;
GetDirectoryPath("lyricPath", ref playMusic.lyricPath);
}
/// <summary>
/// 獲得拖動的檔案的路徑
/// </summary>
/// <param name="label"></param>
/// <param name="path"></param>
public void GetDirectoryPath(string label, ref string path)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(label, GUILayout.MaxWidth(55));
Rect rect = EditorGUILayout.GetControlRect();
path = EditorGUI.TextField(rect, path);
EditorGUILayout.EndHorizontal();
if ((Event.current.type == EventType.DragUpdated
|| Event.current.type == EventType.DragExited)
&& rect.Contains(Event.current.mousePosition))
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
{
path = DragAndDrop.paths[0];
}
}
}
}
/// <summary>
/// 該類引用自 http://www.cnblogs.com/liuxiaobo93/p/3896914.html?from=singlemessage&isappinstalled=0
/// </summary>
[HideInInspector]
public class Lrc
{
#region field
public struct LrcData
{
public float time;
public string timeString;
public string content;
}
public string Title { get; set; }
public string Artist { get; set; }
public string Album { get; set; }
public string LrcBy { get; set; }
public string Offset { get; set; }
public List<LrcData> lrcList = new List<LrcData>();
#endregion
#region public function
/// <summary>
/// 讀取歌詞
/// </summary>
/// <param name="path"></param>
public void ReadLyric(string path)
{
ArrayList list = FileOperate.ReadFile(path);
if (null == list) return;
Regex regextime = new Regex("\\[([0-9.:]*)\\]");
Regex regexword = new Regex(@".*\](.*)");
foreach (string line in list)
{
if (line.StartsWith("[ti:"))
{
Title = SplitInfo(line);
}
else if (line.StartsWith("[ar:"))
{
Artist = SplitInfo(line);
}
else if (line.StartsWith("[al:"))
{
Album = SplitInfo(line);
}
else if (line.StartsWith("[by:"))
{
LrcBy = SplitInfo(line);
}
else if (line.StartsWith("[offset:"))
{
Offset = SplitInfo(line);
}
else
{
try
{
Match mcw = regexword.Match(line);
string word = mcw.Groups[1].Value;
MatchCollection mct = regextime.Matches(line);
foreach (Match item in mct)
{
double time = TimeSpan.Parse("00:" + item.Groups[1].Value).TotalSeconds;
LrcData data = new LrcData();
data.timeString = item.Groups[1].Value;
data.time = (float)time;
data.content = word;
lrcList.Add(data);
}
}
catch
{
continue;
}
}
}
}
#endregion
#region private function
private string SplitInfo(string line)
{
return line.Substring(line.IndexOf(":") + 1).TrimEnd(']');
}
#endregion
}
public class PlayMusic : MonoBehaviour
{
#region field
[HideInInspector]
public string lyricPath;
public AudioSource source;
private int index = 0;
private float time;
private Lrc lrc;
public Action<Lrc.LrcData> OnCurrentLyric;
public Action<float> OnTimeChanaged;
#region encapsulation
public Lrc Lyric
{
get
{
if (null == lrc)
{
lrc = new Lrc();
lrc.ReadLyric(lyricPath);
}
return lrc;
}
}
#endregion
#endregion
#region public function
public int GetIndex()
{
return index;
}
public float GetLength()
{
return source.clip.length;
}
public void Play()
{
index = 0;
source.Play();
}
public void Stop()
{
source.Stop();
}
public void SetNewMusic(AudioClip clip, string lyricPath)
{
if (source.isPlaying)
source.Stop();
source.clip = clip;
this.lyricPath = lyricPath;
Lyric.ReadLyric(lyricPath);
index = 0;
}
/// <summary>
/// 設定開始時間
/// </summary>
/// <param name="value"></param>
public void SetStartTime(float value)
{
source.time = value;
for (int i = 0; i < Lyric.lrcList.Count; i++)
{
if (value < lrc.lrcList[i].time)
{
index = i - 1;
break;
}
}
//有可能找不到時間
if (-1 == index) index = 0;
}
#endregion
#region private function
private void Update()
{
if (source.isPlaying)
{
//如果播放時間改變
if (Mathf.Abs(time - source.time) > 0.01f)
{
time = source.time;
if (null != OnTimeChanaged) OnTimeChanaged(source.time);
}
//如果播放時間大于目前顯示的時間
if (source.time > Lyric.lrcList[index].time)
{
if (null != OnCurrentLyric) OnCurrentLyric(Lyric.lrcList[index]);
index++;
}
}
}
#endregion
}
-------------------------------------測試-------------------------------------
using UnityEngine;
using UnityEngine.UI;
public class View : MonoBehaviour {
public Text content;
public Slider slider;
public PlayMusic playMusic;
private void Awake()
{
slider.maxValue = playMusic.GetLength();
GameObject sliderGame = slider.gameObject;
EventListener.Get(sliderGame).onLeftUp += OnValueChanaged;
EventListener.Get(sliderGame).onLeftDown += OnStop;
playMusic.OnCurrentLyric += OnCurrentLyric;
playMusic.OnTimeChanaged += onTimeChanaged;
}
public void OnClickButton()
{
playMusic.Play();
}
private void OnStop()
{
playMusic.Stop();
}
private void OnValueChanaged()
{
playMusic.SetStartTime(slider.value);
playMusic.Play();
}
private void OnCurrentLyric(Lrc.LrcData data)
{
content.text = data.content;
}
private void onTimeChanaged(float time)
{
slider.value = time;
}
}