C# 简单播放器,音乐播放器,视频播放器,歌词显示,播放列表

原创 小道  2019-01-10 14:20:10  阅读 1021 次 评论 0 条
摘要:

C# 简单播放器,音乐播放器,视频播放器,歌词显示,播放列表,添加列表,删除列表,列表循环,单曲循环,随机循环,音量调节。使用C#制作播放器需要用到Windows Media Player空间。添加Windows Media Player步骤如下:1、工具箱——组件——(右键)选择项——COM 组件——Windows Media Player——确定。设置步骤:将Windows Media Player 组件拖拽到窗体上,右键属性。常规选项:控件布局:选择模式(None)。音量:最大。播放选项:

C# 简单播放器,音乐播放器,视频播放器,歌词显示,播放列表,添加列表,删除列表,列表循环,单曲循环,随机循环,音量调节。

使用C#制作播放器需要用到Windows Media Player空间。

添加Windows Media Player步骤如下:

1、工具箱——组件——(右键)选择项——COM 组件——Windows Media Player——确定。

image.pngimage.pngimage.png

设置步骤:

将Windows Media Player 组件拖拽到窗体上,右键属性。

常规选项:

控件布局:选择模式(None)。

音量:最大。

播放选项:按比例拉伸。

高级选项:

控件设置:

(取消勾选)启动控件。

其中控件布局——选择模式:4中选项。

Full(default)默认选项:除视频或可视化效果窗口之外,内嵌的播放机还具有状态窗口、定位栏、播放/暂停、停止、静音、下一个、上一个、快进、快退以及音量控件。

None:内嵌的播放机不带控件,仅显示视频或可视化效果窗口。

Mini:除视频或可视化效果窗口之外,内嵌的播放机还具有状态窗口、播放/暂停、停止、静音以及音量控件。

Invisible:内嵌的播放机不带控件,不显示视频或可视化效果窗口以及任何用户界面。

默认属性窗口:

image.png

简单播放器设计界面:

image.png

播放按钮,主要注意判断列表内是否有文件,如果没文件不能让播放按钮执行播放。不然会报错。

并且也要判断列表框内是否有选中项。没有选中项,则返回索引为-1.调取 文件路径会报错。

播放和停止按钮代码:

        private void btnPlayOrNo_Click(object sender, EventArgs e)//播放按钮 单击事件
        {
            if (btnPlayOrNo.Text == "播放")//判断 按钮Text是否为 播放。
            {
                if (lbPlayerList.Items.Count == 0)//用于判断 播放列表内是否有播放文件。
                {
                    return;//如果播放列表没有文件,则不执行下面语句。
                }
                //如果不判断是否有文件,点击播放,在下面获取播放文件地址会报错。
                if (b == true)//判断用户之前是否点击过 暂停按钮,点击过暂停按钮则,b为false.
                {
                    if (lbPlayerList.SelectedIndex == -1)//判断列表框中 使用有选择的项,如果没选中项,则为-1.
                    {
                        WMPlayer.URL = listPath[0];//如果用户没有选中列表框中的选项,则将 文件路径list 第一个赋值给播放器。
                        lbPlayerList.SelectedIndex = 0;//列表框选中项设置为第一个。
                    }
                    WMPlayer.URL = listPath[lbPlayerList.SelectedIndex];//如果列表框中用户选中的有项,则将选中项的 文件路径 赋值给播放器。
                    this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                    lbPlayerList.SelectedIndices.Clear();//清除 选中项
                    lbPlayerList.SelectedItem = Path.GetFileName(WMPlayer.URL);//设置选中项
                }
                WMPlayer.Ctlcontrols.play();//播放文件
                btnPlayOrNo.Text = "暂停";//文字改为 暂停
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                lbPlayerList.SelectedIndices.Clear();//清除 选中项
                lbPlayerList.SelectedItem = Path.GetFileName(WMPlayer.URL);//设置选中项
            }
            else if (btnPlayOrNo.Text == "暂停")//判断按钮Text 是否为 暂停.
            {
                WMPlayer.Ctlcontrols.pause();//暂停
                btnPlayOrNo.Text = "播放";//文字改为 播放
                b = false;//设置为 false 说明用户已经点击了暂停按钮。
            }
        }
        private void btnStop_Click(object sender, EventArgs e)//停止按钮
        {
            WMPlayer.Ctlcontrols.stop();//播放器停止。
            lblTime.Text = "00:00:00/00:00:00";//时间标签
            btnPlayOrNo.Text = "播放";//播放按钮 文字
            this.Text = "简单播放器——小道博客https://www.daobk.com";//标题
            tkbMove.Value = 0;//播放滚动条为0
        }

下面主要注意隐藏列表框后要将 其他两个panel 宽度加上。

显示或隐藏列表框代码:

        private void btnList_Click(object sender, EventArgs e)//列表框 点击事件
        {
            int panel1w = panel1.Size.Width;//获取panel1宽度
            int panel1h = panel1.Size.Height;//获取panel1高度
            int panel2w = panel2.Size.Width;//获取panel2宽度
            int panel2h = panel2.Size.Height;//获取panel2高度

            if (grpList.Visible == true)//判断grpList 显示状态
            {
                grpList.Visible = false;//隐藏
                panel1.Size = new Size(panel1w + 158, panel1h);//隐藏列表框后,将panel1 宽度加上 158
                panel2.Size = new Size(panel2w + 158, panel2h);//隐藏列表框后,将panel2 宽度加上 158
            }
            else if (grpList.Visible == false)//判断grpList 显示状态
            {
                grpList.Visible = true;//显示
                panel1.Size = new Size(panel1w - 158, panel1h);//隐藏列表框后,将panel1 宽度减去 158
                panel2.Size = new Size(panel2w - 158, panel2h);//隐藏列表框后,将panel2 宽度减去 158
            }
        }

调用方法参数判断是打开还是添加,如果是打开按钮,则要先清空路径和列表框内容,再添加列表框,并且播放打开的文件,如果是添加按钮,则值添加到列表框中无须播放。

删除要注意要先删除文件路径list,在删除列表框中内容。

打开、添加、删除按钮和添加方法代码:

        private void btnOpen_Click(object sender, EventArgs e)//打开 按钮 单击事件
        {
            addFile((Button)sender);//调用添加文件方法  参数为 是哪个按钮单击的
        }
        private void btnAdd_Click(object sender, EventArgs e)//添加 按钮 单击事件
        {
            addFile((Button)sender);//调用添加文件方法  参数为 是哪个按钮单击的
        }
        private void btnRemove_Click(object sender, EventArgs e)//删除 按钮 单击事件
        {
            int count = lbPlayerList.SelectedItems.Count;//获取选中列表框的项的数目。
            if (count == 0)//判断是否为0,为0表示列表框没有文件。
            {
                return;//不继续执行下面语句。
            }
            if (MessageBox.Show("你确定要移除列表中的 " + count + " 个选中项吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)//提示
            {
                for (int i = 0; i < count; i++)//循环删除
                {
                    listPath.RemoveAt(lbPlayerList.SelectedIndex);//移除 列表框选中对应的 文件路径数组中的元素。
                    lbPlayerList.Items.RemoveAt(lbPlayerList.SelectedIndex);//移除 列表框选中的项
                }
            }
        }
        void addFile(Button sender)//添加文件方法。
        {
            OpenFileDialog ofd = new OpenFileDialog();//提示用户打开文件夹
            ofd.InitialDirectory = @".\";//初始目录
            ofd.Multiselect = true;//可以多选
            ofd.Title = "请选择要打开的文件.";//标题
            ofd.Filter = "支持的全部文件|*.MP3;*.WMA;*.MP4;*.AVI;*.WMV;*.FLV;*.MKV;*.MOV;*.RM;*.RMVB|音乐文件|*.MP3;*.WMA|视频文件|*.MP4;*.AVI;*.WMV;*.FLV;*.MKV;*.MOV;*.RM;*.RMVB|所有文件(*.*)|*.*";
            //扩展名,这里我没全部做测试,其中仅使用MP3、MP4播放。
            ofd.FilterIndex = 1;//获取或设置文件对话框中当前选定筛选器的索引。
            if (ofd.ShowDialog() != DialogResult.OK)//判断用户是否点击了 OK按钮
            {
                MessageBox.Show("请选择要打开的文件!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);//提示
                return;
            }
            if (sender.Name == "btnOpen")//判断传过来的按钮 name
            {
                lbPlayerList.Items.Clear();//清空列表
                listPath.Clear();//清空路径
            }
            string[] path = ofd.FileNames;//获取打开的文件
            for (int i = 0; i < path.Length; i++)//循环
            {
                listPath.Add(path[i]);//将 文件添加到路径
                lbPlayerList.Items.Add(Path.GetFileName(path[i]));//添加到列表
            }
            if (sender.Name == "btnOpen")//判断传过来的按钮 name
            {
                lbPlayerList.SelectedIndex = 0;//将列表选中项设置为第一项
                WMPlayer.URL = listPath[0];//播放路径设置为 路径第一项
                btnPlayOrNo.Text = "暂停";//按钮 文字
                showLrc();//调用歌词
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
            }

        }

以下代码主要注意:双击在空白处的判断。ListBox 设置:SelectionMode 为 MultiExtended  列表框可以多选.

双击列表框代码:

        private void lbPlayerList_DoubleClick(object sender, EventArgs e)//列表框 双击事件
        {
            if (lbPlayerList.Items.Count == 0)//判断列表框 元素个数是否为0
            {
                MessageBox.Show("请先加载要播放的文件到列表中!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);//提示
                return;
            }
            if (lbPlayerList.SelectedIndex == -1)//判断是否有选择项。主要防止 添加文件到列表,没有选中项,双击空白处,报错。
            {
                return;
            }
            WMPlayer.URL = listPath[lbPlayerList.SelectedIndex];//将选中项的路径赋值给播放器
            btnPlayOrNo.Text = "暂停";//按钮 文字
            showLrc();//调用歌词
            this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
        }

以下代码主要注意:循环模式的判断。

上一个、下一个按钮代码:

        private void btnDown_Click(object sender, EventArgs e)//下一个 按钮 
        {
            int index = lbPlayerList.SelectedIndex;//获取选中项索引

            if (btnLoop.Text == "列表循环" || btnLoop.Text == "单曲循环")//判断循环模式
            {
                index++;//索引+1
                if (index >= lbPlayerList.Items.Count)//判断 索引 是否大于 列表元素最大数。
                {
                    index = 0;//索引为0
                }
                WMPlayer.URL = listPath[index];//赋值播放器
                lbPlayerList.SelectedIndices.Clear();//清除 选中项
                lbPlayerList.SelectedIndex = index;//设置选中项
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
            }
            else if (btnLoop.Text == "随机播放")//判断循环模式
            {
                int num = r.Next(0, lbPlayerList.Items.Count);//随机 0~列表元素总数值。
                WMPlayer.URL = listPath[num];//赋值播放器
                lbPlayerList.SelectedIndices.Clear();//清除 选中项
                lbPlayerList.SelectedIndex = num;//设置选中项
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
            }
        }

        private void btnUp_Click(object sender, EventArgs e)//上一个
        {
            int index = lbPlayerList.SelectedIndex;//获取选中项索引

            if (btnLoop.Text == "列表循环" || btnLoop.Text == "单曲循环")//判断循环模式
            {
                index--;//索引-1
                if (index < 0)//判断 索引 是否小于0。
                {
                    index = lbPlayerList.Items.Count - 1;//索引为 列表总数数-1
                }
                WMPlayer.URL = listPath[index];//赋值播放器
                lbPlayerList.SelectedIndices.Clear();//清除 选中项
                lbPlayerList.SelectedIndex = index;//设置选中项
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
            }
            else if (btnLoop.Text == "随机播放")//判断循环模式
            {
                int num = r.Next(0, lbPlayerList.Items.Count);//随机 0~列表元素总数值。
                WMPlayer.URL = listPath[num];//赋值播放器
                lbPlayerList.SelectedIndices.Clear();//清除 选中项
                lbPlayerList.SelectedIndex = num;//设置选中项
                this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
            }
        }

以下代码主要注意:要保存当前音量大小数据,用于 按下静音和恢复声音后的音量值。

音量标签和滚动条代码:

        private void AMain_Load(object sender, EventArgs e)//窗体默认加载
        {
            volumeNum = WMPlayer.settings.volume;//获取音量的值
            trbVolume.Maximum = 100;//音量滚动条 最大值
            trbVolume.Minimum = 0;//音量滚动条 最小值
            trbVolume.TickFrequency = 3;//获取或设置一个值,该值指定控件上绘制的刻度之间的增量。
            trbVolume.Value = 100;//当前滚动条的位置
            label1.Text = trbVolume.Value.ToString() + "%";//在音量 标签显示音量值
            tkbMove.LargeChange = 10;//播放进度 滚动条 滚动距离
        }
        private void label1_Click(object sender, EventArgs e)//音量 标签 单击
        {
            if (label1.Tag.ToString() == "1")//判断Tag 值
            {
                WMPlayer.settings.mute = true;//音量关闭
                label1.Tag = "2";//设置为2
                label1.Image = Properties.Resources.音量关;//图标
                trbVolume.Value = 0;//音量 滚动条为0
            }
            else if (label1.Tag.ToString() == "2")//判断Tag 值
            {
                WMPlayer.settings.mute = false;//音量打开
                label1.Tag = "1";//设置为1
                label1.Image = Properties.Resources.音量开;//图标
                trbVolume.Value = volumeNum;//音量滚动条恢复
            }
        }
        private void trbVolume_ValueChanged(object sender, EventArgs e)//音量 滚动条 值发生变化
        {
            WMPlayer.settings.volume = trbVolume.Value;//将滚动条 值赋值给音量

            if (trbVolume.Value == 0)//判断滚动条值是否为0
            {
                label1.Image = Properties.Resources.音量关;//图标
                label1.Tag = "2";//Tag设置为2
                label1.Text = "";//为空
            }
            else
            {
                volumeNum = WMPlayer.settings.volume;//将音量值赋值给 volumeNum 用于记录 音量值
                label1.Text = trbVolume.Value.ToString() + "%";//在音量 标签显示音量值
                label1.Image = Properties.Resources.音量开;//图标
                label1.Tag = "1";//Tag设置为1
            }
        }

以下代码主要注意:当前播放进度与总时长,判断是否播放完毕,要总时长-1 == 当前播放进度。

播放时间时钟代码:

        private void timerPlay_Tick(object sender, EventArgs e)//播放时间 时钟
        {
            tkbMove.Minimum = 0;//播放 滚动条最小值
            if (WMPlayer.playState == WMPLib.WMPPlayState.wmppsPlaying)//判断当前 是否在播放文件
            {
                showLrc();//调用歌词
                string playTime = WMPlayer.Ctlcontrols.currentPositionString;//获取当前播放的时间,格式 00:00
                lblTime.Text = playTime + "/" + WMPlayer.currentMedia.durationString;//将当前播放时间/文件总时间 显示在标签上,格式: 00:50/03:20
                tkbMove.Maximum = (int)WMPlayer.currentMedia.duration;//获取文件总长度,格式如: 229.334
                tkbMove.Value = (int)WMPlayer.Ctlcontrols.currentPosition;//获取当前播放长度,格式如:158.2564589

                if (tkbMove.Maximum - 1 == tkbMove.Value)//判断当总时间-1  是否等于 当前播放时间
                {
                    int index = lbPlayerList.SelectedIndex;//获取当前选中项的索引

                    if (btnLoop.Text == "列表循环")//判断循环模式
                    {
                        index++;//索引+1
                        if (index >= lbPlayerList.Items.Count)//判断 索引 是否大于 列表元素最大数。
                        {
                            index = 0;//索引为0
                        }
                        WMPlayer.URL = listPath[index];//赋值播放器
                        lbPlayerList.SelectedIndices.Clear();//清除 选中项
                        lbPlayerList.SelectedIndex = index;//设置 选中项
                        this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                    }
                    else if (btnLoop.Text == "单曲循环")//判断循环模式
                    {
                        if (index == -1)//判断索引是否为 -1  主要为了防止 选择单曲循环,并删除列表当前选中项,这时索引为-1.会报错
                        {
                            index = 0;//索引设置为0
                            lbPlayerList.SelectedIndex = index;//设置 选中项
                            this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                        }
                        WMPlayer.URL = listPath[index];//赋值播放器
                        this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                    }
                    else if (btnLoop.Text == "随机播放")//判断循环模式
                    {
                        int num = r.Next(0, lbPlayerList.Items.Count);
                        WMPlayer.URL = listPath[num];//赋值播放器
                        lbPlayerList.SelectedIndices.Clear();//清除 选中项
                        lbPlayerList.SelectedIndex = num;//设置 选中项
                        this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
                    }
                }
            }
        }

以下代码主要注意: 要添加 鼠标松开 后事件,最好将当前线程挂起100毫秒,不然拖放滚动条,画面会卡顿。

播放进度滚动条代码:

        private void tkbMove_MouseUp(object sender, MouseEventArgs e)//播放滚动条 移动
        {
            Thread.Sleep(100);//将当前线程挂起指定的时间。
            if (tkbMove.Value >= (int)WMPlayer.currentMedia.duration)//判断当前播放进度 是否大于或等于 播放总长度
            {
                if ((int)WMPlayer.currentMedia.duration == 0)//判断播放总长度是否为0
                {
                    return;
                }
                tkbMove.Value = (int)WMPlayer.currentMedia.duration - 1;//设置 滚动条值为 总长度-1
            }
            WMPlayer.Ctlcontrols.currentPosition = tkbMove.Value;//滚动条值赋值给 当前播放进度
        }

        private void tkbMove_Scroll(object sender, EventArgs e)// 播放 滚动条 滚动
        {
            if (Control.MouseButtons == MouseButtons.None)//判断是否是 鼠标拖动 滚动条
            {
                if (tkbMove.Value >= (int)WMPlayer.currentMedia.duration)//判断当前播放进度 是否大于或等于 播放总长度
                {
                    if ((int)WMPlayer.currentMedia.duration - 1 == -1)//判断总长度-1 是否等于-1
                    {
                        return;
                    }
                    tkbMove.Value = (int)WMPlayer.currentMedia.duration - 1;//设置 滚动条值为 总长度-1
                }
                WMPlayer.Ctlcontrols.currentPosition = tkbMove.Value;//滚动条值赋值给 当前播放进度
            }
        }

显示歌词本来想使用GDI+  显示全部歌词,并高亮 当前歌词。想想还是后期 学习了美化播放器UI界面,在做把。歌词只测试了一个,下面代码可能会有Bug。

歌词显示或隐藏代码:

        private void btnLrc_Click(object sender, EventArgs e)//歌词按钮 单击事件
        {
            if (btnLrc.Tag.ToString() == "1")//判断Tag 值
            {
                if (WMPlayer.URL == "")//判断 播放链接是否为空
                {
                    return;
                }
                showLrc();//调用歌词
                btnLrc.BackColor = SystemColors.ControlDark;//按钮背景颜色
                btnLrc.Tag = "2";//Tag值为2
                WMPlayer.Visible = false;//播放器 设置隐藏
                lblLrc.Visible = true;//显示歌词 标签
            }
            else if (btnLrc.Tag.ToString() == "2")//判断Tag 值
            {
                btnLrc.BackColor = SystemColors.Control;//按钮背景颜色
                btnLrc.Tag = "1";//Tag值为1
                lblLrc.Visible = false;//隐藏 歌词标签
                WMPlayer.Visible = true;//显示播放器
            }
        }
        List<double> listTime = new List<double>();//存放 歌词事件
        List<string> listLrcText = new List<string>();//存放歌词
        void showLrc()//歌词方法
        {
            string lrcPath = WMPlayer.URL.Substring(0, WMPlayer.URL.LastIndexOf(".")) + ".lrc";//查找是否存在歌词,比如:歌曲名:ABC.mp3,那么歌词名为:ABC.lrc
            if (File.Exists(lrcPath) == false)//判断歌词是否存在
            {
                timerLrc.Enabled = false;//歌词时钟 关闭
                lblLrc.TextAlign = ContentAlignment.MiddleCenter;//对齐方式
                lblLrc.Font = new Font("宋体", 20, FontStyle.Bold);//字体
                lblLrc.ForeColor = Color.Blue;//颜色
                lblLrc.Text = "---------未找到歌词---------";//显示
                return;
            }
            timerLrc.Enabled = true;//歌词时钟 打开
            string[] lrcText = File.ReadAllLines(lrcPath);//读取歌词文件内容
            for (int i = 0; i < lrcText.Length; i++)//循环
            {
                string[] lrcTemp = lrcText[i].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
                //分割 时间和歌词
                if (lrcTemp.Length != 2)//判断lrcTemp数组 长度 不等于2
                {
                    continue;//退出本次循环
                }
                string[] lrcNewTemp = lrcTemp[0].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                //分割时间
                double timeM;//分钟
                double timeS;//秒数
                if (double.TryParse(lrcNewTemp[0], out timeM) == false)//判断 转换失败
                {
                    continue;//退出本次循环
                }
                if (double.TryParse(lrcNewTemp[1], out timeS) == false)//判断 转换失败
                {
                    continue;//退出本次循环
                }

                double time = (timeM * 60) + timeS;//获取总秒数
                listTime.Add(time);//添加 歌词时间list
                listLrcText.Add(lrcTemp[1]);//添加 歌词list
            }
        }
        private void timerLrc_Tick(object sender, EventArgs e)//歌词 时钟
        {
            lblLrc.TextAlign = ContentAlignment.MiddleCenter;//对齐方式
            lblLrc.Font = new Font("宋体", 20, FontStyle.Bold);//字体 大小
            lblLrc.ForeColor = Color.Blue;//颜色
            for (int i = 0; i < listTime.Count; i++)//循环
            {
                if (i == listTime.Count - 1)//判断当前i的值是否为listTime 最后一个值,如果没这句判断,到最后一行货报错。
                {
                    if (WMPlayer.Ctlcontrols.currentPosition >= listTime[i])//当前播放进度是否大于 歌词时间
                    {
                        lblLrc.Text = listLrcText[i];//显示歌词
                    }
                    return;
                }
                if (WMPlayer.Ctlcontrols.currentPosition >= listTime[i] && WMPlayer.Ctlcontrols.currentPosition < listTime[i + 1])//当前播放进度是否大于 歌词时间,并且当前播放进度小于 下一句歌词时间
                {
                    lblLrc.Text = listLrcText[i];//显示歌词
                }
            }
        }

运行界面:

image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png


暂未添加功能:UI界面美化、网络播放(导入网上视频地址,在线播放。)、添加文件夹到列表、播放列表保存、视频倍速播放、视频全屏播放,视频打开原始尺寸播放等功能。

如需本软件完整源码请留言!仅限学习交流使用!


简单播放器来源:本站
已经过安全软件检测无毒,请您放心下载。
本文地址:https://www.daobk.com/post/166.html
版权声明:本文为原创文章,版权归 小道 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?