• 【笔记】歌词显示问题


    上节写了如何从千千静听服务器下载歌词,这节说说如何让歌词显示出来

      首先是分析歌词文件,分析出不同时间对于的歌词

    1、定义一个歌词行的类LrcLineItem

            public class LrcLineItem
            {
                public string TimeString { get; set; }
                public string Text { get; set; }
                public double Time { get; set; }
    
                public LrcLineItem(string text, double time)
                {
                    this.Text = text;
                    this.Time = time;
                    
                    //[02:13.60]歌词
                    int timeint = (int)this.Time;
                    this.TimeString = "[" + (timeint / 60).ToString("d2") + ":" + (timeint % 60).ToString("d2") + (Time - timeint).ToString("f2").Substring(1, 3) + "]" + Text;
                }
    
                public override string ToString()
                {
                    return this.TimeString;
                }
            }

    然后计算出歌词中所有的不同时间对于的歌词存放到LrcLineItem数组中

    下面定义LrcAnalyze类

        public class LrcAnalyze
        {
            string title;
            string artist;
            string album;
            string content;
            List<LrcLineItem> lrcList;
    
            public LrcLineItem[] lrcs { get; set; }
    
            public LrcAnalyze(string filepath)
            {
                lrcList = new List<LrcLineItem>();
                using (StreamReader reader = new StreamReader(filepath, Encoding.UTF8))
                {
                    content = reader.ReadToEnd();
                }
                Analyze();
            }
    
            private void Analyze()
            {
                StringReader reader = new StringReader(content);
                
                string lineStr = reader.ReadLine();
                while (lineStr !=null)
                {
                    if (lineStr != null && lineStr.Length > 3)
                    {
                        switch (lineStr.Substring(1, 2))
                        {
                            case "ti":
                                title = lineStr.Substring(4, lineStr.Length - 5);
                                break;
                            case "ar":
                                artist = lineStr.Substring(4, lineStr.Length - 5);
                                break;
                            case "al":
                                album = lineStr.Substring(4, lineStr.Length - 5);
                                break;
                            default:
                                GetLrcStr(lineStr);
                                break;
                        }
                    }
                    lineStr = reader.ReadLine();
    
                }
                //排序(冒泡)
                SortLrcLine();
            }
    
            private void GetLrcStr(string lineStr)
            {
                int num = (lineStr.LastIndexOf(']') + 1) / 10;
                string text = lineStr.Substring(num * 10);
    
                try
                {
                    for (int i = 0; i < num; i++)
                    {
                        string timestr = lineStr.Substring(i * 10 + 1, 8);
                        double time = Convert.ToDouble(timestr.Substring(0, 2)) * 60 + Convert.ToDouble(timestr.Substring(3, 5));
                        lrcList.Add(new LrcLineItem(text, time));
                    }
                }
                catch(FormatException)
                {
                }
            }
    
            private void SortLrcLine()
            {
                lrcs = lrcList.ToArray();
                for (int i = 0; i < lrcs.Length - 1; i++)
                {
                    for (int j = i + 1; j < lrcs.Length; j++)
                    {
                        if (lrcs[i].Time > lrcs[j].Time)
                        {
                            LrcLineItem temp = lrcs[j];
                            lrcs[j] = lrcs[i];
                            lrcs[i] = temp;
                        }
                    }
    
                }
            }
    
            //获得相应时间的歌词,返回索引
            public int GetIndex(double time)
            {
                for (int i = 0; i < lrcs.Length; i++)
                {
                    if (lrcs[i].Time > time)
                    {
                        return i - 1;
                    }
                }
                return lrcs.Length - 1;
            }
    
            //返回多行歌词(count*2+1行)
            public string[] GetLrcStrings(int count, double time)
            {
                int index = GetIndex(time);
    
                string[] lrcstrings = new string[count * 2 + 1];
                for (int i = 0; i < count; i++)
                {
                    if (index - count + i > 0)
                        lrcstrings[i] = lrcs[index - count + i].Text;
                    else
                        lrcstrings[i] = string.Empty;
                }
                lrcstrings[count] = lrcs[index].Text;
                for (int i = 0; i < count; i++)
                {
                    if (index + i < lrcs.Length)
                        lrcstrings[count + i + 1] = lrcs[index + i].Text;
                    else
                        lrcstrings[i] = string.Empty;
                }
                return lrcstrings;
            }
        }

    好了,歌词的分析算是完成了,接下来实践一下

      1、创建一个WinForm窗体,添加7个Label控件分别是Label1,Labe2l,Label3,Label4,Label5,Label6,Label7,用于显示歌词,其中Label4的颜色设为红色,其他设为白色

      2、添加一个按钮Play,用于开始播放音乐

      3、定义两个文件Lrc和Mp3,这里的Mp3文件用之前讲的 AxWindowsMediaPlayer播放

            string musicfile = @"G:\Music\郭峰 - 心甘情愿.mp3";
            string lrcfile = @"G:\Music\郭峰 - 心甘情愿.lrc";

      4、添加一个计时器timer1,用于计算当前播放,时间间隔设为500,没半秒刷新一次歌词,添加触发事件

      5、为axWindowsMediaPlayer1添加一个事件函数PositionChange,当进度条改变时,time也相应改变

    代码如下

            public partial class Form1 : Form
            {
                double time = 0;        //当前播放时间
                LrcAnalyze lrc;            //歌词信息
    
                string musicfile = @"G:\Music\郭峰 - 心甘情愿.mp3";
                string lrcfile = @"G:\Music\郭峰 - 心甘情愿.lrc";
    
                public Form1()
                {
                    InitializeComponent();
                    lrc = new LrcAnalyze(lrcfile);
                }
    
                private void timer1_Tick(object sender, EventArgs e)
                {
                    this.time = this.time + 0.5;
                    //更新UI
                    string[] strs = this.lrc.GetLrcStrings(3, time);
                    this.label1.Text = strs[0];
                    this.label2.Text = strs[1];
                    this.label3.Text = strs[2];
                    this.label4.Text = strs[3];
                    this.label5.Text = strs[4];
                    this.label6.Text = strs[5];
                    this.label7.Text = strs[6];
                }
    
                private void axWindowsMediaPlayer1_PositionChange(object sender, AxWMPLib._WMPOCXEvents_PositionChangeEvent e)
                {
                    this.time = e.newPosition;
                }
    
                private void btnPlay_Click(object sender, EventArgs e)
                {
                    this.axWindowsMediaPlayer1.URL = musicfile;
                    this.axWindowsMediaPlayer1.Ctlcontrols.play();
                    this.timer1.Start();
                }
            }

  • 相关阅读:
    C#|.NET从控制反转(依赖注入)想到事件注入 (非AOP)
    libevent 2.1.3 for VS2008 source code
    如何进行object以及Array(数组)的深复制
    Flash ProgressEvent.bytesTotal为0的原因和解决
    Flash字体嵌入方法总结—(4)进阶篇
    mysql分组取每组前几条记录(排名) 附group by与order by的研究
    Flash游戏优化技巧
    教程:深入理解Flash的沙箱 – Application Domains
    Flash Player 11异步解码Bitmap
    常用公式
  • 原文地址:https://www.cnblogs.com/bomo/p/2820217.html
Copyright © 2020-2023  润新知