欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Unity實(shí)現(xiàn)卡拉OK歌詞過(guò)渡效果

 更新時(shí)間:2019年06月19日 11:03:47   作者:月兒圓  
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)卡拉OK歌詞過(guò)渡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

好長(zhǎng)時(shí)間之前做過(guò)的一個(gè)項(xiàng)目 , 其中設(shè)計(jì)到用Unity模擬卡拉OK歌詞過(guò)渡的效果 , 如下圖所示 ↓ , 這里簡(jiǎn)單把原理部分分享一下.
文章目錄

  • 演示效果 ↓
  • 歌詞效果類(lèi) ↓
  • 配套資源下載

演示效果 ↓

  • 實(shí)現(xiàn)歌詞動(dòng)態(tài)調(diào)整功能
  • 實(shí)現(xiàn)動(dòng)態(tài)讀取歌詞文件功能
  • 實(shí)現(xiàn)歌曲快進(jìn)快退功能
  • 實(shí)現(xiàn)歌曲單字時(shí)間匹配功能
  • 實(shí)現(xiàn)可動(dòng)態(tài)更換歌詞前景色背景色功能

注:

這里為實(shí)現(xiàn)精準(zhǔn)過(guò)渡效果使用的是KSC歌詞文件, 并不是LRC文件哦 .

這其中我認(rèn)為就是如何實(shí)現(xiàn)歌詞部分的前景色向后景色過(guò)渡的效果了, 開(kāi)始的時(shí)候我想的也是很復(fù)雜 , 使用Shader的形式實(shí)現(xiàn) ,網(wǎng)上找了一些相關(guān)代碼 , 發(fā)現(xiàn)不是特別理想 , 最終還是自己嘗試著用Mask來(lái)實(shí)現(xiàn)的, 發(fā)現(xiàn)效果還不錯(cuò) !
因?yàn)榻裉煜掳嗑瓦^(guò)年回家啦! 其他細(xì)節(jié)之后會(huì)完善的 , 今天把工程文件先上傳了 .

歌詞效果類(lèi) ↓

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using DG.Tweening;
using DG.Tweening.Core;

/// <summary>
/// 用于顯示歌詞過(guò)渡的效果
/// 1. 獲得路徑加載并解析歌詞文件信息
/// 2. 判斷當(dāng)前歌曲是否播放( 歌曲暫停的時(shí)候歌詞效果也暫停 , 歌曲停止的時(shí)候歌詞效果消失 )
/// 3. 判斷歌曲快進(jìn)或快退事件
/// </summary>
public class LayricPanelEffect : MonoSingleton<LayricPanelEffect>
{
 #region *********************************************************************字段

 //由外部傳入的聲音資源
 [HideInInspector,SerializeField]
 public AudioSource audioSource;
 //歌詞前景顏色;歌詞后景顏色
 [SerializeField]
 public Color32 frontTextColor = Color.white, backTextColor = Color.black, outlineColor = Color.white;
 //歌詞面板的前景部分和后景部分
 public RectTransform rectFrontLyricText, rectBackLyricMask;
 public Slider slider;
 //歌詞文件路徑
 [HideInInspector,SerializeField]
 public string lyricFilePath;

 //是否開(kāi)始播放當(dāng)前行歌詞內(nèi)容
 public bool isStartLyricEffectTransition = true;
 //歌詞調(diào)整進(jìn)度 ( 糾錯(cuò) )
 // [HideInInspector]
 public float lyricAdjust = -5f;

 //歌詞文本信息
 // [HideInInspector]
 [SerializeField,HideInInspector]
 public Text _lyricText;
 public Text _textContentLyric, _textLogMessage;

 private Vector2 tempFrontSizeDelta, tempBackSizeDelta;

 //用于訪問(wèn)歌詞正文部分的內(nèi)容在KscWord類(lèi)中
 private KSC.KscWord kscword = new KSC.KscWord ();
 private KSC.KscWord curKscword = new KSC.KscWord ();

 //內(nèi)部定時(shí)器( 由外部傳入?yún)?shù)來(lái)控制 , 用來(lái)記錄歌曲播放的當(dāng)前時(shí)間軸 )
 private float _timer = 0.00f;

 #endregion

 /// <summary>
 /// 初始化一些變量
 /// </summary>
 void InitSomething ()
 {
 //堅(jiān)持對(duì)歌詞文件進(jìn)行賦值操作
 if (_lyricText == null || rectFrontLyricText.GetComponent <ContentSizeFitter> () == null) {
 if (rectFrontLyricText.GetComponent <Text> () == null) {
 _lyricText = rectFrontLyricText.gameObject.AddComponent <Text> ();
 }
 _lyricText = rectFrontLyricText.GetComponent <Text> ();

 //保持歌詞實(shí)現(xiàn)自適應(yīng)
 rectFrontLyricText.GetComponent <ContentSizeFitter> ().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
 rectFrontLyricText.GetComponent <ContentSizeFitter> ().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
 }
 rectBackLyricMask.GetComponentInChildren <Text> ().text = _lyricText.text;

 //歌詞顏色的更改初始化
 rectBackLyricMask.GetComponentInChildren <Text> ().color = backTextColor;
 rectBackLyricMask.GetComponentInChildren <Outline> ().effectColor = outlineColor;
 rectFrontLyricText.GetComponent <Text> ().color = frontTextColor;

 //歌詞過(guò)渡的前景部分 ( 用于判斷過(guò)度遮罩的長(zhǎng)度范圍 )
 tempFrontSizeDelta = rectFrontLyricText.sizeDelta;
 tempBackSizeDelta = rectBackLyricMask.sizeDelta;

 //是否開(kāi)始當(dāng)前歌詞行播放標(biāo)志位
 isStartLyricEffectTransition = true;
 }

 void Awake ()
 { 
 //初始化
 InitSomething ();
 }

 /// <summary>
 /// 控制歌詞面板的顯示
 /// 1. 僅僅顯示歌詞面板信息 , 沒(méi)有過(guò)渡效果!
 /// </summary>
 /// <param name="row">歌詞正文部分行號(hào).</param>
 /// <param name="isPanelView">If set to <c>true</c> 顯示面板歌詞</param>
 public void LyricPanelControllerView (KSC.KscWord curRowInfo, bool isPanelView)
 {
// Debug.Log ("當(dāng)前行是否開(kāi)始=====>" + isPanelView.ToString ());
 _textLogMessage.text = isStartLyricEffectTransition.ToString ();

 rectBackLyricMask.sizeDelta = new Vector2 (0f, rectFrontLyricText.sizeDelta.y);

 rectBackLyricMask.GetComponentInChildren <Text> ().text = _lyricText.text = "";
 if (isPanelView) {
 //根據(jù)時(shí)間得到當(dāng)前播放的是第i行的歌詞
 //處理歌詞面板信息 , 顯示歌詞
 foreach (var item in curRowInfo.PerLineLyrics) {
 _lyricText.text += item;
 rectBackLyricMask.GetComponentInChildren<Text> ().text = _lyricText.text;
 }
 StartCoroutine (LyricPanelControllerEffect (curRowInfo, isPanelView));
 } else {
 StopAllCoroutines ();
 rectBackLyricMask.sizeDelta = new Vector2 (0f, rectFrontLyricText.sizeDelta.y);
// StartCoroutine (LyricPanelControllerEffect (curRowInfo, isPanelView));
 //當(dāng)前歌詞結(jié)束以后將歌詞框初始化成0
 rectBackLyricMask.GetComponentInChildren <Text> ().text = _lyricText.text = string.Empty;
 }
 }

 /// <summary>
 /// 開(kāi)始實(shí)現(xiàn)歌此過(guò)渡效果, 僅僅效果實(shí)現(xiàn)
 /// 1. 使用Dotween的doSizedata實(shí)現(xiàn)
 /// 2. 動(dòng)態(tài)調(diào)整蒙板的sizedata寬度
 /// 3. 根據(jù)歌曲當(dāng)前播放的時(shí)間進(jìn)度進(jìn)行調(diào)整
 /// </summary>
 /// <returns>The panel controller effect.</returns>
 /// <param name="isPanelEffect">If set to <c>true</c> is panel effect.</param>
 public IEnumerator LyricPanelControllerEffect (KSC.KscWord curRowInfo, bool isPanelEffect)
 {
 //當(dāng)前時(shí)間歌詞播放進(jìn)度的百分比比例
 int curWordIndex = 0;
 if (isPanelEffect) {
 rectBackLyricMask.DORewind ();
 yield return null;
 rectBackLyricMask.sizeDelta = new Vector2 (0f, rectFrontLyricText.sizeDelta.y);
 //開(kāi)始效果過(guò)渡
 if (audioSource.isPlaying) {
 for (int i = 0; i < curKscword.PerLinePerLyricTime.Length; i++) {
 rectBackLyricMask.DOSizeDelta (
 new Vector2 (((float)(i + 1) / curKscword.PerLinePerLyricTime.Length) * rectFrontLyricText.sizeDelta.x, rectFrontLyricText.sizeDelta.y)
 , curKscword.PerLinePerLyricTime [i] / 1000f
 , false).SetEase (Ease.Linear);
// Debug.Log ("第" + i + "個(gè)歌詞時(shí)間");
 yield return new WaitForSeconds (curKscword.PerLinePerLyricTime [i] / 1000f);
 }
 } else {
 Debug.LogError ("歌曲沒(méi)有播放 !?。?!");
 }
 } else {
 yield return null;
 rectBackLyricMask.DOSizeDelta (new Vector2 (0f, rectFrontLyricText.sizeDelta.y), 0f, true);
 }
 }

 /// <summary>
 /// 開(kāi)始播放音樂(lè)的時(shí)候調(diào)用
 /// </summary>
 /// <param name="lyricFilePath">歌詞文件路徑.</param>
 /// <param name="audioSource">Audiosource用于判斷播放狀態(tài).</param>
 /// <param name="frontColor">前景色.</param>
 /// <param name="backColor">后景.</param>
 /// <param name="isIgronLyricColor">如果設(shè)置為 <c>true</c> 則使用系統(tǒng)配置的默認(rèn)顏色.</param>
 public void StartPlayMusic (string lyricFilePath, AudioSource audioSource, Color frontColor, Color backColor, Color outlineColor, bool isIgronLyricColor)
 {
 _timer = 0f;

 //初始化ksc文件
 KSC.InitKsc (lyricFilePath);

 this.lyricFilePath = lyricFilePath;
 this.audioSource = audioSource;

 _textContentLyric.text = string.Empty;

 if (!isIgronLyricColor) {
 //歌曲顏色信息
 this.frontTextColor = frontColor;
 this.backTextColor = backColor;
 this.outlineColor = outlineColor;
 }

 #region ****************************************************輸出歌詞文件信息
 //對(duì)初始化完成后的信息進(jìn)行輸出
 if (KSC.Instance.SongName != null) {
 print ("歌名==========>" + KSC.Instance.SongName);
 }
 if (KSC.Instance.Singer != null) {
 print ("歌手==========>" + KSC.Instance.Singer);
 }
 if (KSC.Instance.Pinyin != null) {
 print ("拼音==========>" + KSC.Instance.Pinyin);
 }
 if (KSC.Instance.SongClass != null) {
 print ("歌類(lèi)==========>" + KSC.Instance.SongClass);
 }
 if (KSC.Instance.InternalNumber > 0) {
 print ("歌曲編號(hào)=======>" + KSC.Instance.InternalNumber);
 }
 if (KSC.Instance.Mcolor != Color.clear) {
 print ("男唱顏色=======>" + KSC.Instance.Mcolor);
 }
 if (KSC.Instance.Mcolor != Color.clear) {
 print ("女唱顏色=======>" + KSC.Instance.Wcolor);
 }
 if (KSC.Instance.SongStyle != null) {
 print ("風(fēng)格==========>" + KSC.Instance.SongStyle);
 }
 if (KSC.Instance.WordCount > 0) {
 print ("歌名字?jǐn)?shù)=======>" + KSC.Instance.WordCount);
 }
 if (KSC.Instance.LangClass != null) {
 print ("語(yǔ)言種類(lèi)=======>" + KSC.Instance.LangClass);
 }

 //一般是獨(dú)唱歌曲的時(shí)候使用全Tag標(biāo)簽展現(xiàn)參數(shù)信息
 foreach (var item in KSC.Instance.listTags) {
 print (item);
 }
 #endregion

 //顯示整個(gè)歌詞內(nèi)容
 for (int i = 0; i < KSC.Instance.Add.Values.Count; i++) {
 KSC.Instance.Add.TryGetValue (i, out kscword);
 for (int j = 0; j < kscword.PerLineLyrics.Length; j++) {
 _textContentLyric.text += kscword.PerLineLyrics [j];
 }
 _textContentLyric.text += "\n";
 }
 }

 /// <summary>
 /// 停止播放按鈕
 /// </summary>
 public void StopPlayMusic ()
 {
 Debug.Log ("停止播放按鈕");
 }

 /// <summary>
 /// 主要用于歌詞部分的卡拉OK過(guò)渡效果
 /// 1. 動(dòng)態(tài)賦值歌詞框的長(zhǎng)度
 /// 2. 支持快進(jìn)快退同步顯示
 /// </summary>
 int row = 0, tempRow = 0;

 void FixedUpdate ()
 {
 #region *********************************************************播放過(guò)渡效果核心代碼
 //如果是播放狀態(tài)并且沒(méi)有快進(jìn)或快退 , 獲得當(dāng)前播放時(shí)間 , 如果都下一句歌詞了 , 則切換到下一句歌詞進(jìn)行過(guò)渡效果
 //1. 是否是暫停;
 //2. 是否開(kāi)始播放
 //3. 是否播放停止
 if (audioSource != null && audioSource.isPlaying) {
 //進(jìn)度條
 slider.value = _timer / audioSource.clip.length;
 //快進(jìn)快退快捷鍵
 if (Input.GetKey (KeyCode.RightArrow)) {
 audioSource.time = Mathf.Clamp ((audioSource.time + 1f), 0f, 4.35f * 60f);
 } else if (Input.GetKey (KeyCode.LeftArrow)) {
 audioSource.time = Mathf.Clamp ((audioSource.time - 1f), 0f, 4.35f * 60f);
// } else if (Input.GetKeyUp (KeyCode.LeftArrow)) {
 isStartLyricEffectTransition = true;
 rectBackLyricMask.GetComponentInChildren <Text> ().text = rectFrontLyricText.GetComponent <Text> ().text = string.Empty;
 }

 //實(shí)時(shí)計(jì)時(shí)
 _timer = audioSource.time;

 //歌曲開(kāi)始播放的時(shí)間
 _textLogMessage.text = _timer.ToString ("F2");

 for (int i = 0; i < KSC.Instance.Add.Count; i++) {

 KSC.Instance.Add.TryGetValue (i, out kscword);

 //根據(jù)時(shí)間判斷當(dāng)前播放的是哪一行的歌詞文件 ( 減去0.01可保證兩句歌詞銜接太快的時(shí)候的bug )
 if ((_timer >= (kscword.PerLineLyricStartTimer + lyricAdjust + 0.1f) && _timer <= (kscword.PerLintLyricEndTimer + lyricAdjust - 0.1f)) && isStartLyricEffectTransition) {
 tempRow = i;
 KSC.Instance.Add.TryGetValue (tempRow, out curKscword);
 isStartLyricEffectTransition = false;
 Debug.Log ("當(dāng)前播放====>" + i + "行");
 //歌詞面板顯示當(dāng)前播放內(nèi)容
 LyricPanelControllerView (curKscword, !isStartLyricEffectTransition);
 } else if ((_timer >= (curKscword.PerLintLyricEndTimer + lyricAdjust)) && !isStartLyricEffectTransition) {
 isStartLyricEffectTransition = true;
 //設(shè)置不顯示歌詞內(nèi)容
 LyricPanelControllerView (curKscword, !isStartLyricEffectTransition);
 } 
 }

// KSC.Instance.Add.TryGetValue (row, out kscword);
//
// //根據(jù)時(shí)間判斷當(dāng)前播放的是哪一行的歌詞文件 ( 減去0.01可保證兩句歌詞銜接太快的時(shí)候的bug )
// if ((_timer >= (kscword.PerLineLyricStartTimer + lyricAdjust + 0.1f) && _timer <= (kscword.PerLintLyricEndTimer + lyricAdjust)) && isStartLyricEffectTransition) {
// tempRow = row;
// KSC.Instance.Add.TryGetValue (tempRow, out curKscword);
// isStartLyricEffectTransition = false;
// Debug.Log ("當(dāng)前播放====>" + row + "行");
// //歌詞面板顯示當(dāng)前播放內(nèi)容
// LyricPanelControllerView (curKscword, !isStartLyricEffectTransition);
// } else if ((_timer >= (curKscword.PerLintLyricEndTimer + lyricAdjust)) && !isStartLyricEffectTransition) {
// isStartLyricEffectTransition = true;
// //設(shè)置不顯示歌詞內(nèi)容
// LyricPanelControllerView (curKscword, !isStartLyricEffectTransition);
// row = (row + 1) % KSC.Instance.Add.Count;
// } 
 #endregion
 }
 }
}

###KSC文件解析類(lèi) ↓

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using UnityEngine.UI;
using System;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;

/// <summary>
/// KSC歌詞文件解析屬性, 單例工具類(lèi) ( 解析解析解析解析解析解析解析解析解析!!!!!!重要的事情多說(shuō)幾遍 )
/// 1. 歌詞部分標(biāo)題信息用單例instance訪問(wèn)
/// 2. 正文信息部分使用KSCWord對(duì)象訪問(wèn)( 每句開(kāi)始時(shí)間\結(jié)束時(shí)間\每句歌詞文字的數(shù)組\每句歌詞文件時(shí)間的數(shù)組 )
/// </summary>
public class KSC : Singleton<KSC>
{
 /// <summary>
 /// 歌曲 歌名
 /// </summary>
 public string SongName { get; set; }

 /// <summary>
 /// 歌名字?jǐn)?shù) 歌名字?jǐn)?shù)
 /// </summary>
 public int WordCount{ get; set; }

 /// <summary>
 /// 歌名字?jǐn)?shù) 歌名的拼音聲母
 /// </summary>
 public string Pinyin{ get; set; }

 /// <summary>
 /// 歌名字?jǐn)?shù) 歌曲語(yǔ)言種類(lèi)
 /// </summary>
 public string LangClass{ get; set; }

 /// <summary>
 /// 歌類(lèi),如男女樂(lè)隊(duì)等
 /// </summary>
 public string SongClass{ get; set; }

 /// <summary>
 /// 藝術(shù)家 演唱者,對(duì)唱?jiǎng)t用斜杠"/"分隔
 /// </summary>
 public string Singer { get; set; }

 /// <summary>
 /// 歌曲編號(hào) 歌曲編號(hào)
 /// </summary>
 public int InternalNumber{ get; set; }

 /// <summary>
 /// 歌曲風(fēng)格
 /// </summary>
 public string SongStyle{ get; set; }

 /// <summary>
 /// 視頻編號(hào) 
 /// </summary>
 public string VideoFileName{ get; set; }

 /// <summary>
 /// 前景顏色
 /// </summary>
 public Color Mcolor{ get; set; }

 /// <summary>
 /// 后景顏色
 /// </summary>
 public Color Wcolor{ get; set; }

 /// <summary>
 /// 偏移量
 /// </summary>
 public string Offset { get; set; }

 /// <summary>
 /// 各類(lèi)標(biāo)簽
 /// </summary>
 public List<string> listTags = new List<string> ();

 /// <summary>
 /// 歌詞正文部分信息 ( key = 行號(hào) value = 解析出來(lái)的歌詞正文部分的每句歌詞信息 )
 /// </summary>
 public Dictionary<int,KscWord> Add = new Dictionary<int, KscWord> ();


 /// <summary>
 /// 獲得歌詞信息
 /// </summary>
 /// <param name="LrcPath">歌詞路徑</param>
 /// <returns>返回歌詞信息(Lrc實(shí)例)</returns>
 public static KSC InitKsc (string LrcPath)
 {
 int row = 0;
 //KscWord對(duì)象
 //清除之前的歌曲歌詞, 保持當(dāng)前
 KSC.Instance.Add.Clear ();
 using (FileStream fs = new FileStream (LrcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
 string line = string.Empty;
 using (StreamReader sr = new StreamReader (fs, Encoding.Default)) {
 
 while ((line = sr.ReadLine ()) != null) {
 //每次循環(huán)新建一個(gè)對(duì)象用于存儲(chǔ)不同行數(shù)內(nèi)容
 KSC.KscWord kscWord = new KSC.KscWord ();
 #region ######################################合唱歌曲格式
 if (line.StartsWith ("karaoke.songname := '")) {
 Instance.SongName = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.internalnumber := ")) {
 if (SplitIntInfo (line) != 0) {
 Instance.InternalNumber = SplitIntInfo (line);
 }
 } else if (line.StartsWith ("karaoke.singer := '")) {
 Instance.Singer = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.wordcount := ")) {
 if (SplitIntInfo (line) != 0) {
 Instance.WordCount = SplitIntInfo (line);
 }
 } else if (line.StartsWith ("karaoke.pinyin := '")) {
 Instance.Pinyin = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.langclass := '")) {
 Instance.LangClass = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.songclass := '")) {
 Instance.SongClass = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.songstyle := '")) {
 Instance.SongStyle = SplitStrInfo (line);
 } else if (line.StartsWith ("karaoke.videofilename :='")) {
 Instance.VideoFileName = SplitStrInfo (line);
 } else if (line.StartsWith ("mcolor :=rgb(")) {
 if (SplitColorInfo (line) != Color.clear) {
 Instance.Mcolor = SplitColorInfo (line);
 }
 } else if (line.StartsWith ("wcolor :=rgb(")) {
 if (SplitColorInfo (line) != Color.clear) {
 Instance.Wcolor = SplitColorInfo (line);
 }
 #endregion

 #region ##################################################獨(dú)唱歌曲風(fēng)格
 } else if (line.StartsWith ("karaoke.tag('")) {
 //獲取tag標(biāo)簽的參數(shù)信息
 KSC.Instance.listTags.Add (SplitTagInfo (line));
 #endregion 

 #region ################################################歌詞正文部分解析
 } else if (line.StartsWith (("karaoke.add"))) {   //表示歌詞正文部分
 if (SplitLyricStartTime (line) != null) {
 //行號(hào) ( 從0行開(kāi)始 )

 //獲取每句歌詞部分的開(kāi)始時(shí)間
 kscWord.PerLineLyricStartTimer = SplitLyricStartTime (line);
 //獲取每句歌詞部分的結(jié)束時(shí)間
 kscWord.PerLintLyricEndTimer = SplitLyricEndTime (line);
 //獲取每行歌詞的內(nèi)容,并存儲(chǔ)到KSCWord中 ( 歌詞文字的數(shù)組信息 左 → 右 )
 kscWord.PerLineLyrics = SplitPerLineLyrics (line);
 //獲取每行中單個(gè)文字的過(guò)渡時(shí)間數(shù)組 ( 歌詞文字過(guò)渡時(shí)間數(shù)組 左 → 右 )
 kscWord.PerLinePerLyricTime = SplitPerLinePerLyricTime (line);
 KSC.Instance.Add.Add (row, kscWord);
 row++;
 }
 } else {
 //忽略ksc文件中的其他部分
 if (line != "" && !line.Contains ("CreateKaraokeObject") && !line.Contains ("karaoke.rows") && !line.Contains ("karaoke.clear;") && !Regex.IsMatch (line, @"^\//")) {
 Debug.LogWarning ("歌詞含有不能解析的部分 ===> " + line);
 }
 }
 #endregion
 }
 }
 } 
 Debug.Log ("LyricFileInitialized" + " Path : \n" + LrcPath);
 return Instance;
 }

 #region ****************************************************************解析歌詞用的正則表達(dá)式部分 需更新

 /// <summary>
 /// 處理信息(私有方法)
 /// </summary>
 /// <param name="line"></param>
 /// <returns>返回基礎(chǔ)信息</returns>
 public static string SplitStrInfo (string line)
 {
// char[] ch = new char[]{ '\0', '\0' };
// return line.Substring (line.IndexOf ("'") + 1).TrimEnd (ch);
 string pattern = @"'\S{1,20}'"; //獲取歌曲標(biāo)簽信息
 Match match = Regex.Match (line, pattern);

 //去除兩端的小分號(hào)
 string resout = string.Empty;
 resout = match.Value.Replace ("\'", string.Empty);
 return resout;
 }

 /// <summary>
 /// 處理參數(shù)是數(shù)字的情況
 /// </summary>
 /// <returns>The int info.</returns>
 /// <param name="line">Line.</param>
 public static int SplitIntInfo (string line)
 {
 string pattern = @"\d+"; //獲取歌曲標(biāo)簽參數(shù)為數(shù)字的信息
 Match match = Regex.Match (line, pattern);

 //去除兩端的小分號(hào)
 int result = 0;
 result = Int32.Parse (match.Value);
 return result;
 }

 /// <summary>
 /// 處理參數(shù)顏色色值的情況 如: mcolor :=rgb(0, 0, 255);
 /// </summary>
 /// <returns>The color info.</returns>
 /// <param name="line">Line.</param>
 public static Color32 SplitColorInfo (string line)
 {
 string pattern = @"[r,R][g,G][b,G]?[\(](2[0-4][0-9])|25[0-5]|[01]?[0-9][0-9]?"; //獲取歌曲標(biāo)簽參數(shù)為顏色值的信息
 MatchCollection matches = Regex.Matches (line, pattern);

 return new Color (float.Parse (matches [0].ToString ()), float.Parse (matches [1].ToString ()), float.Parse (matches [2].ToString ()));
 }

 /// <summary>
 /// 獲取歌曲的標(biāo)簽部分信息 如 : karaoke.tag('語(yǔ)種', '國(guó)語(yǔ)'); // 國(guó)語(yǔ)/粵語(yǔ)/臺(tái)語(yǔ)/外語(yǔ)
 /// </summary>
 /// <returns>The tag info.</returns>
 public static string SplitTagInfo (string line)
 {
 string temp;
 string pattern = @"\([\W|\w]+\)"; //獲取歌曲標(biāo)簽參數(shù)為顏色值的信息
 Match match = Regex.Match (line, pattern);
 temp = match.Value.Replace ("(", string.Empty).Replace (")", string.Empty).Replace ("'", string.Empty).Replace (",", ":");
 return temp;
 }

 /// <summary>
 /// 獲取每句歌詞正文部分的開(kāi)始時(shí)間 (單位 : 秒)
 /// </summary>
 /// <returns>The lyric start time.</returns>
 /// <param name="line">Line.</param>
 public static float SplitLyricStartTime (string line)
 {
 float time = 0f;
 Regex regex = new Regex (@"\d{2}:\d{2}\.\d{2,3}", RegexOptions.IgnoreCase); //匹配單句歌詞時(shí)間 如: karaoke.add('00:29.412', '00:32.655'
 MatchCollection mc = regex.Matches (line);
 time = (float)TimeSpan.Parse ("00:" + mc [0].Value).TotalSeconds;
 return time;
 }

 /// <summary>
 /// 獲取每句歌詞正文部分的結(jié)束時(shí)間 (單位 : 秒)
 /// </summary>
 /// <returns>The lyric start time.</returns>
 /// <param name="line">Line.</param>
 public static float SplitLyricEndTime (string line)
 {
 Regex regex = new Regex (@"\d{2}:\d{2}\.\d{2,3}", RegexOptions.IgnoreCase); //匹配單句歌詞時(shí)間 如: karaoke.add('00:29.412', '00:32.655'
 MatchCollection mc = regex.Matches (line);
 float time = (float)TimeSpan.Parse ("00:" + mc [1].Value).TotalSeconds;
 return time;
 }

 /// <summary>
 /// 獲取每句歌詞部分的每個(gè)文字 和 PerLinePerLyricTime相匹配 (單位 : 秒)
 /// </summary>
 /// <returns>The line lyrics.</returns>
 /// <param name="line">Line.</param>
 public static string[] SplitPerLineLyrics (string line)
 {
 List<string> listStrResults = new List<string> ();
 string pattern1 = @"\[[\w|\W]{1,}]{1,}"; //獲取歌曲正文每個(gè)單詞 如 : karaoke.add('00:25.183', '00:26.730', '[五][十][六][個(gè)][星][座]', '312,198,235,262,249,286');
 string pattern2 = @"\'(\w){1,}\'"; //獲取歌曲正文每個(gè)單詞 如 : karaoke.add('00:28.420', '00:35.431', '夕陽(yáng)底晚風(fēng)里', '322,1256,2820,217,1313,1083');
 Match match = (line.Contains ("[") && line.Contains ("]")) ? Regex.Match (line, pattern1) : Regex.Match (line, pattern2);
 //刪除掉 [ ] '
 if (match.Value.Contains ("[") && match.Value.Contains ("]")) { //用于合唱類(lèi)型的歌詞文件
 string[] resultStr = match.Value.Replace ("][", "/").Replace ("[", string.Empty).Replace ("]", string.Empty).Split ('/');
 foreach (var item in resultStr) {
 listStrResults.Add (item);
 }
 } else if (match.Value.Contains ("'")) {  //用于獨(dú)唱類(lèi)型的歌詞文件 ( 尚未測(cè)試英文歌詞文件!!!!!!!!!!!!!!!!!!!!!!! )
 char[] tempChar = match.Value.Replace ("'", string.Empty).ToCharArray ();
 foreach (var item in tempChar) {
 listStrResults.Add (item.ToString ());
 }
 }
 return listStrResults.ToArray ();
 }

 /// <summary>
 /// 獲取每句歌詞部分的每個(gè)文字需要的過(guò)渡時(shí)間 和 PerLineLyrics相匹配 (單位 : 秒)
 /// </summary>
 /// <returns>The line per lyric time.</returns>
 /// <param name="line">Line.</param>
 public static float[] SplitPerLinePerLyricTime (string line)
 {
 string pattern = @"\'((\d){0,}\,{0,1}){0,}\'"; //獲取歌曲正文每個(gè)單詞過(guò)渡時(shí)間 如 : karaoke.add('00:25.183', '00:26.730', '[五][十][六][個(gè)][星][座]', '312,198,235,262,249,286');

 string str = null;
 List<float> listfloat = new List<float> ();
 //刪除掉 多余項(xiàng)
 str = Regex.Match (line, pattern).Value.Replace ("'", string.Empty);
// Debug.Log (str);
 foreach (var item in str.Split (',')) {
 listfloat.Add (float.Parse (item));
 }
 return listfloat.ToArray ();
 }

 #endregion

 #region ********************************************************************歌詞正文部分的時(shí)間與文字信息

 /// <summary>
 /// 用單獨(dú)的類(lèi)來(lái)管理歌詞的正文部分 ( 在KSC類(lèi)下 )主要用來(lái)存儲(chǔ)每句歌詞和每個(gè)歌詞的時(shí)間信息
 /// 1. 每句歌詞的時(shí)間的 ( 開(kāi)始 - 結(jié)束 )
 /// 2. 每句歌詞中單個(gè)文字的時(shí)間信息 (集合的形式實(shí)現(xiàn))
 /// </summary>
 public class KscWord
 {
 /// <summary>
 /// 每行歌詞部分開(kāi)始的時(shí)間 (單位 : 秒) (key=行號(hào),value=時(shí)間)
 /// </summary>
 public float PerLineLyricStartTimer { get; set; }

 /// <summary>
 /// 每行歌詞部分結(jié)束時(shí)間 (單位 : 秒) (key=行號(hào),value=時(shí)間)
 /// </summary>
 public float PerLintLyricEndTimer { get; set; }

 /// <summary>
 /// 每行歌詞的單個(gè)文字集合
 /// </summary>
 public string[] PerLineLyrics{ get; set; }

 /// <summary>
 /// 每行歌詞中單個(gè)文字的速度過(guò)渡信息 (單位 : 毫秒)
 /// </summary>
 public float[] PerLinePerLyricTime{ get; set; }
 }

 #endregion
}

不敢說(shuō)代碼如何清新脫俗 , 自己也在學(xué)習(xí)的路上 , 有程序愛(ài)好者想要交流的話(huà)歡迎交流啊 . 有心的朋友可以看看 , 年后看時(shí)間再完善啦

配套資源下載

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#使用CefSharp自定義緩存實(shí)現(xiàn)

    C#使用CefSharp自定義緩存實(shí)現(xiàn)

    本文介紹了如何使用C#和CefSharp自定義緩存實(shí)現(xiàn)減少Web應(yīng)用程序的網(wǎng)絡(luò)請(qǐng)求,提高應(yīng)用程序性能。首先,本文講解了CefSharp的基本知識(shí)和使用方法。然后,詳細(xì)闡述了在CefSharp中實(shí)現(xiàn)自定義緩存的步驟和技巧。最后,通過(guò)實(shí)例演示了如何使用自定義緩存功能獲取并展示網(wǎng)頁(yè)數(shù)據(jù)
    2023-04-04
  • C#比較時(shí)間大小的方法總結(jié)

    C#比較時(shí)間大小的方法總結(jié)

    在本篇內(nèi)容里小編給大家分享的是關(guān)于C#比較時(shí)間大小的方法總結(jié),對(duì)此有需要的朋友們可以學(xué)習(xí)下。
    2018-12-12
  • Avalonia封裝實(shí)現(xiàn)指定組件允許拖動(dòng)的工具類(lèi)

    Avalonia封裝實(shí)現(xiàn)指定組件允許拖動(dòng)的工具類(lèi)

    這篇文章主要為大家詳細(xì)介紹了Avalonia如何封裝實(shí)現(xiàn)指定組件允許拖動(dòng)的工具類(lèi),文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C#關(guān)鍵字之覆寫(xiě)overwrite介紹

    C#關(guān)鍵字之覆寫(xiě)overwrite介紹

    這篇文章介紹了C#關(guān)鍵字之覆寫(xiě)overwrite,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的代碼詳解

    C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的代碼詳解

    這篇文章主要介紹了C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的的方法,涉及C#調(diào)用windows系統(tǒng)命令實(shí)現(xiàn)控制開(kāi)機(jī)、關(guān)機(jī)等操作的技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2024-02-02
  • C#實(shí)現(xiàn)簡(jiǎn)單聊天程序的方法

    C#實(shí)現(xiàn)簡(jiǎn)單聊天程序的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)簡(jiǎn)單聊天程序的方法,實(shí)例分析了C#聊天程序的原理與客戶(hù)端、服務(wù)器端的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • C# DialogResult用法案例詳解

    C# DialogResult用法案例詳解

    這篇文章主要介紹了C# DialogResult用法案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C#實(shí)現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法

    C#實(shí)現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法

    眾所周知R軟件功能非常強(qiáng)大,可以很好的進(jìn)行各類(lèi)統(tǒng)計(jì),并能輸出圖形。下面介紹一種R語(yǔ)言和C#進(jìn)行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細(xì),需要的朋友可以參考下。
    2017-02-02
  • Unity利用UGUI制作提示框效果

    Unity利用UGUI制作提示框效果

    這篇文章主要為大家詳細(xì)介紹了Unity利用UGUI制作提示框效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C# ConfigHelper 輔助類(lèi)介紹

    C# ConfigHelper 輔助類(lèi)介紹

    ConfigHelper(包含AppConfig和WebConfig), app.config和web.config的[appSettings]和[connectionStrings]節(jié)點(diǎn)進(jìn)行新增、修改、刪除和讀取相關(guān)的操作。
    2013-04-04

最新評(píng)論