基于QT的网络音乐播放器(四)

关于歌词的显示,其实我的主要思想就是解析歌词部分的字符串。歌词显示分为两部分,一部分是播放器右侧的歌词显示以及下面的桌面歌词的显示。其中桌面歌词让我很难受,想了很久,后面看到一个大佬的一篇文章后才有了思路。

先看效果图:

在这里插入图片描述

其实就是解析lrc歌词字符串。lrc歌词分为两部分,前面部分是时间,后面一部分是歌词。得到时间和歌词,保存下来。我是用两个list保存的,其实后面一想,用map来保存其实更好。但是我没有改,你们可以改一下,用map来保存。
在这里插入图片描述

比如时间为00:40.11的时候歌词为:微笑在天上飞

在QMediaPlayer的positionChanged消息的相应函数里面。对比时间,现在播放的时间处于前面记录下来的时间的list中的哪两个之间,就显示相应的歌词。

桌面歌词:

桌面歌词其实就是重写paintevent函数,把文字绘制两遍,第一遍是原始颜色的歌词内容,第二遍是需要改变颜色的内容。就是使用有色的字绘制第二遍,把前面那一次绘制的一部分字遮住,就实现了这个效果。
看代码吧:

void lrc_widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setFont(font);

    //先绘制底层文字,作为阴影
    painter.setPen(Qt::white);
    painter.drawText(0,0,QFontMetrics(font).boundingRect(str1).width(),this->height()/2,Qt::AlignLeft,str1);
    painter.drawText(0,this->height()/2,QFontMetrics(font).boundingRect(str2).width(),this->height()/2,Qt::AlignLeft,str2);

    //设置歌词遮罩
    if(isFirst)
    {
        painter.setPen(QPen(linearGradient,0));
        if(Proportion != 0)
        {
            painter.drawText(0,0,QFontMetrics(font).boundingRect(str1).width()*(lrci/double(Proportion)),this->height()/2,Qt::AlignLeft,str1);
        }
    }
    else
    {
        painter.setPen(QPen(linearGradient,0));
        if(Proportion != 0)
        {
            painter.drawText(0,this->height()/2,QFontMetrics(font).boundingRect(str2).width()*(lrci/double(Proportion)),this->height()/2,Qt::AlignLeft,str2);
        }
    }
}

其中str1为第一行歌词,str2为第二行歌词

QMediaPlayer的positionChanged消息的相应函数:

void Widget::on_player_position_change(qint64 position)                         //播放歌曲进度改变,改变时间显示,歌词改变
{
    ui->seekSlider->setValue(position);
    music_position = position;

    int h = music_position/3600000;
    int m = (music_position%3600000)/60000;
    int s = ((music_position%3600000)%60000)/1000;
    int ms = ((music_position%3600000)%60000)%1000;
    QString timestr;
    QTime time(h,m,s,ms);
    ui->now_time_label->setText(time.toString("hh:mm:ss"));

    QTime time2(h,m,s,ms);
    timestr = time2.toString("mm:ss");

    for(int i = 0;i < lrcTime.count();i++)
    {
        if(time <= QTime::fromString(lrcTime.at(i),"mm:ss:zzz"))
        {
            // i 为下一次唱的歌词
            QString mm1;
            QString ss1;
            QString zzz1;
            QString mm2;
            QString ss2;
            QString zzz2;

            if(lrcindex != i || i == 0)
            {
                if(i == 0)
                {
                    myLrc_widget->setLabel_1_text(lrcStr.at(i));
                    myLrc_widget->setLabel_2_text(lrcStr.at(i + 1));
                }
                else
                {
                    if(nowIsFirst)
                    {
                        myLrc_widget->setLabel_2_text(lrcStr.at(i));
                        nowIsFirst = !nowIsFirst;
                    }
                    else
                    {
                        myLrc_widget->setLabel_1_text(lrcStr.at(i));
                        nowIsFirst = !nowIsFirst;
                    }
                }
                if(lrcindex <= 4)              //前5行   直接下来  歌词不变
                {
                    ui->Lrc_list->item(lrcindex)->setTextColor(Qt::red);
                    for(int j = 0;j < lrcindex;j++)
                    {
                        ui->Lrc_list->item(j)->setTextColor(Qt::black);
                    }
                }
                else            //超过5   通过改变每行显示的歌词来改变进度
                {
                    for(int j = 0;j < 4;j++)
                    {
                        ui->Lrc_list->item(j)->setText(lrcStr.at(lrcindex - 4 + j));
                    }
                    for(int j = 0;j < 6;j++)
                    {
                        if(lrcindex + j < lrcStr.count())
                        {
                            ui->Lrc_list->item(4+j)->setText(lrcStr.at(lrcindex + j));
                        }
                        else
                        {
                            ui->Lrc_list->item(4+j)->setText("");
                        }
                    }
                }
                lrcindex = i;
            }
            if(i != 0)
            {
                mm1 = QString(lrcTime.at(i)).split(":").at(0);
                ss1 = QString(lrcTime.at(i)).split(":").at(1);
                zzz1 = QString(lrcTime.at(i)).split(":").at(2);

                mm2 = QString(lrcTime.at(i - 1)).split(":").at(0);
                ss2 = QString(lrcTime.at(i - 1)).split(":").at(1);
                zzz2 = QString(lrcTime.at(i - 1)).split(":").at(2);
                int y = (mm1.toInt() - mm2.toInt())*60*1000 + (ss1.toInt() - ss2.toInt())*1000 + (zzz1.toInt() - zzz2.toInt());
                int x = (m - mm2.toInt())*60*1000 + (s - ss2.toInt())*1000 + (ms - zzz2.toInt());
                myLrc_widget->setProportion(x,y);
            }
            break;
        }
    }

}

这就是所有的歌词显示部分的内容,可能有些地方说得不明白,如果大家哪里有问题的可以问,或者有什么更好的建议,我看到了就回复。大家互相学习。

上一篇:调用API解析数据

项目源码下载地址:https://download.csdn.net/download/qq_37141865/10703635

猜你喜欢

转载自blog.csdn.net/qq_37141865/article/details/82953027