【笔记】歌词显示问题

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

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

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();
            }
        }

 

 

 

 

 

 

posted @ 2012-12-16 11:21  bomo  阅读(1068)  评论(0编辑  收藏  举报