基於QT實現簡單的音樂播放器

基於QT實現一個多功能媒體播放器,它能播放音頻(如mp3),視頻
媒體播放器界面,有進度條,可展現總播放時間、當前播放時間,進度條可拖動,有播放、暫停鍵,有快進、快退鍵,上一曲下一曲,靜音,調節音量,雙擊播放歌曲,以及簡單的歌詞同步。
主界面以下:
在這裏插入圖片描述
建立三個本地文件夾分別存放MV,歌詞和音樂文件
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
工程結構目錄以下(整個結構沒有設計好,因此每一個視頻都要單首創建文件):
在這裏插入圖片描述
mainwindow.h代碼以下:










javascript

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QMediaPlayer>
#include <QStringList>
#include <QDir>
#include <QTime>
#include <QTimer>
#include<videoplayer.h>
#include<videoplayer_qr.h>
#include<videoplayer_cq.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    VideoPlayer *v1;
    videoplayer_qr *v_qr;
    videoplayer_cq *v_cq;

    bool isPlay=false;
    bool ismute=false;
    QString MusicPath="C:\\Users\\44637\\Music\\QTMusic";
    QString LrcPath="C:\\Users\\44637\\Music\\QTLrc";

    QStringList fileList;   //文件名稱
    QStringList lrcList;
    QMediaPlaylist *PlayerList;
    QMediaPlayer *Player;
    int   moved;
    int iCount=0;
    QTimer *timer2;
    QMap<int, QString> map;
    QMap<QString, QString> *map2;
    void getHeader(const char *str, QString &des);
    void getTime(QString line);//改動二



private slots:
    void init();//初始化
    void addItem(QString name); //把歌名添加到musicname上
    QStringList getFileNames(const QString &path);  //獲取路徑下全部文件名
     QStringList getLrcNames(const QString &path);  //獲取路徑下全部文件名
    void slotButtonStart();//播放
    void slotButtonLast();//上一首
    void slotButtonNext();//下一首
    void slotShowCurrentMusic();//顯示當前播放的歌曲
    void volumChange(int);//控制音量
    void positionChange(qint64 position);//進度條隨着音樂播放變化
    void seekChange(int position);  //滑動滑動條快進、倒退音樂,且音樂已播放時長也跟着變化
    void musicTime();//歌曲總時間
    void slotShowCurrentLrc();
    void showWord(int time);//顯示歌詞
    void initlrc(const QString& fileName);//初始化歌詞
    void button_style();//按鈕樣式
    void changestartbutton();
    void cleanmap();
    void playto(int i,int );//雙擊播放
    void video_click_wm();//播放相應視頻
    void video_click_qr();
    void video_click_cq();
    void mute();//靜音
    void fastForward();//快進
    void fastBack();//快退

};
#endif // MAINWINDOW_H

mainwindow.cpp代碼以下:java

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotButtonStart);
    connect(ui->Buttonlast,&QPushButton::clicked,this,&MainWindow::slotButtonLast);
    connect(ui->Buttonnext,&QPushButton::clicked,this,&MainWindow::slotButtonNext);
    connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::changestartbutton);
    connect(ui->Buttonvideo_wm,&QPushButton::clicked,this,&MainWindow::video_click_wm);
    connect(ui->Buttonvideo_qr,&QPushButton::clicked,this,&MainWindow::video_click_qr);
    connect(ui->Buttonvideo_cq,&QPushButton::clicked,this,&MainWindow::video_click_cq);
    connect(ui->Buttonmute,&QPushButton::clicked,this,&MainWindow::mute);
    connect(ui->fastButton,&QPushButton::clicked,this,&MainWindow::fastForward);
    connect(ui->fastbackButton,&QPushButton::clicked,this,&MainWindow::fastBack);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init(){
    button_style();

    PlayerList = new QMediaPlaylist;    //實例化播放器和播放列表
    Player = new QMediaPlayer;
    fileList = getFileNames(this->MusicPath);   //獲取文件夾下全部音樂文件
    lrcList = getLrcNames(this->LrcPath);
    moved = 0;
    qDebug()<<"ALL Music File \n"<<fileList;
    qDebug()<<"ALL Lrc File \n"<<lrcList;


    for(int i=0;i<fileList.size();i++){
        QString fileName=fileList.at(i);
        addItem(fileName);
        PlayerList->addMedia(QUrl::fromLocalFile(MusicPath+"\\"+fileName));
    }
    PlayerList->setCurrentIndex(0);
    Player->setPlaylist(PlayerList);    //將播放列表加載到播放器

    connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::slotShowCurrentMusic);
    connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::slotShowCurrentLrc);
    connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::cleanmap);
    connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);
    connect(ui->Buttonnext,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);
    connect(ui->Buttonlast,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);
    connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotShowCurrentMusic);
    connect(ui->Volumebar, SIGNAL(sliderMoved(int)), this, SLOT(volumChange(int)));

    connect(Player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChange(qint64)));
    connect(Player,SIGNAL(durationChanged(qint64)),this,SLOT(musicTime()));
    connect(ui->Progressbar,SIGNAL(sliderMoved(int)),this,SLOT(seekChange(int)));

    connect(ui->musicname,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(playto(int,int)));
}


QStringList MainWindow::getFileNames(const QString &path)
{
    QDir dir(path);
    QStringList nameFilters;
    nameFilters << "*.mp3";
    QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);
    return files;
}

QStringList MainWindow::getLrcNames(const QString &path)
{
    QDir dir(path);
    QStringList nameFilters;
    nameFilters <<"*.txt";
    QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);
    return files;
}

void MainWindow::addItem(QString name){
    int count = ui ->musicname->rowCount();
    ui->musicname->setRowCount(count+1);
    QTableWidgetItem *itemName = new QTableWidgetItem(name);
    itemName->setFlags(itemName->flags() & ~Qt::ItemIsEditable);
    ui->musicname->setItem(count,0,itemName);
}

void MainWindow::slotShowCurrentMusic(){
    int index=PlayerList->currentIndex();
    QString songName=fileList.at(index);
    ui->CurrentMusic->setText(songName);
}

void MainWindow::slotShowCurrentLrc(){
    int index=PlayerList->currentIndex();
    qDebug()<<index;
    QString musicLrc=lrcList.at(index);
    qDebug()<<musicLrc;
    initlrc(musicLrc);

}

void MainWindow::slotButtonStart(){
    if(!isPlay){
        isPlay=true;
        Player->setVolume(100);
        Player->play();
        musicTime();

    }
    else{
        isPlay=false;
        Player->pause();
        musicTime();
    }
}

void MainWindow::slotButtonLast(){
    int currentIndex = PlayerList->currentIndex();
    if(currentIndex == 0){
        currentIndex=PlayerList->mediaCount();
    }
    else{
    PlayerList->previous();
    PlayerList->previousIndex();
    musicTime();
    }
}

void MainWindow::slotButtonNext(){
    int currentIndex = PlayerList->currentIndex();
    if(++currentIndex == PlayerList->mediaCount()){
    currentIndex=0;}
    PlayerList->setCurrentIndex(currentIndex);
    musicTime();
}

void MainWindow::volumChange(int vol)
{
    Player -> setVolume(vol);
}

void MainWindow::positionChange(qint64 position)
{
    ui->Progressbar->setMaximum(Player->duration() / 1000);//設置滑塊的長度範圍爲音樂長.00度
    ui->Progressbar->setValue(position / 1000);//若是音樂進度改變,則改變滑塊顯示位置
    moved = position;//讓播放時間等於音樂進度(毫秒)
    QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//設置時間
    ui->showPro ->setText(moveTime.toString("mm:ss"));//顯示時間
    QString t=moveTime.toString("mm:ss");
    QString mm = t.mid(0,2);
    QString ss = t.mid(3, 2);
    int m = mm.toInt();
    int s = ss.toInt();
    int time = m*60*1000 + s*1000;
    showWord(time);
}

void MainWindow::seekChange(int position)
{
    Player -> setPosition(position * 1000);//若是滑塊改變位置,則改變音樂進度
    moved = position * 1000;//讓播放時間等於音樂進度(毫秒)
    QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//設置時間
    ui->showPro ->setText(moveTime.toString("mm:ss"));//顯示時間

}

void MainWindow::musicTime(){

                qint64 time = Player->duration();
                QTime Time(0,(time % (1000 * 60 * 60)) / (1000 * 60),(time % (1000 * 60)) / 1000);
                    ui->MusicTime->setText(Time.toString("mm:ss"));
                qDebug()<<"time:"<<Time;

}


void MainWindow::showWord(int time)
{
    if(map.contains(time))
    {
        ui->label1->setText(map.value(time));

    }
    else{
        qDebug()<<"繼續上一句歌詞";
    }
}

void MainWindow::getHeader(const char *str, QString &des)
{
    des = des.remove(str);
    des = des.remove("]");
}

void MainWindow::getTime(QString line)//獲取lrc文件的每句的時間
{
    if(line.startsWith("["))
    {
        int index = line.indexOf("]");
        QString t = line.mid(1, index - 1);
        QString mm = t.mid(0,2);
        QString ss = t.mid(3, 2);
        int m = mm.toInt();
        int s = ss.toInt();
        int time = m*60*1000 + s*1000;
        t = line.mid(index + 1);
        index = t.lastIndexOf("]");
        if(index < 0)
        {
            map.insert(time, t);
        }
        else
        {
            t = t.mid(index + 1);
            map.insert(time, t);
            getTime(t);
            qDebug()<<"time123:"<<time;
        }
    }
}

void MainWindow::initlrc(const QString& fileName)
{
    QMap<int, QString> map;
    QString l;
    QFile file("C:\\Users\\44637\\Music\\QTLrc\\"+fileName);
    if(file.exists()){
        qDebug()<<"文件存在";
    }
    else{
        qDebug()<<"文件不存在";
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        return;
    }

    QTextCodec *codec = QTextCodec::codecForName("GBK");
    while(!file.atEnd())
    {

        QString line = codec->toUnicode(file.readLine());
        QString s(line);
        if(s.length()<4)
                    continue;
                if(s.startsWith("[ti:"))
                {
                    getHeader("[ti:", s);
                    map.insert(0, s);
                    ui->topmusicname->setText(s);
                    continue;
                }
                else if(s.startsWith("[ar:"))
                {
                    getHeader("[ar:", s);
                    map.insert(1000, s);
                    ui->singer->setText("歌手:"+s);
                    continue;
                }
                else if(s.startsWith("[al:"))
                {
                    getHeader("[al:", s);
                    map.insert(2000, s);
                    ui->album->setText("專輯:"+s);
                    continue;
                }
                else if(s.startsWith("[by:"))
                {
                    getHeader("[by:", s);
                    map.insert(3000, s);
                    continue;
                }
                else
                {

                    getTime(s);
                }

}
    file.close();

}


void MainWindow::button_style(){
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));
    ui->Buttonlast->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\last.jpg"));
    ui->Buttonnext->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\next.png"));
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));
    ui->Buttonvideo_qr->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));
    ui->Buttonvideo_wm->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));
    ui->Buttonvideo_cq->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));    
}


void MainWindow::changestartbutton(){
    if(isPlay)
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));
    else
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));
}

void MainWindow::cleanmap(){
    map.clear();
}


void MainWindow::playto(int i,int )
{
    PlayerList->setCurrentIndex(i);
    isPlay=true;
    changestartbutton();
    QString musicLrc=lrcList.at(i);
    initlrc(musicLrc);
    Player->play();
}


void MainWindow::video_click_wm(){
    v1= new VideoPlayer(this);
    v1->setModal(false);
    v1->show();
}

void MainWindow::video_click_qr(){
    v_qr= new videoplayer_qr(this);
    v_qr->setModal(false);
    v_qr->show();
}

void MainWindow::video_click_cq(){
    v_cq= new videoplayer_cq(this);
    v_cq->setModal(false);
    v_cq->show();
}

void MainWindow::mute(){
    if(!ismute){
    Player -> setVolume(0);
    //ui->voiceslider->value();
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\mute.png"));
    ismute=true;
    }
    else{
    Player -> setVolume(100);
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));
    ismute=false;
    }
}

void MainWindow::fastForward(){
    qint64 position=Player->position();
    qDebug()<<"position"<<position;
    position=position+5000;
    ui->Progressbar->setValue(position/1000);
    Player -> setPosition(position);//若是滑塊改變位置,則改變音樂進度
}

void MainWindow::fastBack(){
    qint64 position=Player->position();
    qDebug()<<"position"<<position;
    position=position-5000;
    ui->Progressbar->setValue(position/1000);
    Player -> setPosition(position);//若是滑塊改變位置,則改變音樂進度

}

videoplayer.h代碼以下(視頻播放和音樂播放差很少):ide

#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H

#include <QDialog>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QMediaPlaylist>
#include <QTime>
#include <QTimer>

namespace Ui {
class VideoPlayer;
}

class VideoPlayer : public QDialog
{
    Q_OBJECT

public:
    explicit VideoPlayer(QWidget *parent = nullptr);
    ~VideoPlayer();

public slots:
    void init();
    void slotButtonStart();
    void slotstop();
    void closeEvent(QCloseEvent *);
    void volumChange(int);
    void positionChange(qint64 position);
    void seekChange(int position);  //滑動滑動條快進、倒退音樂,且音樂已播放時長也跟着變化
    void videoTime();
    void changestartbutton();
    void button_style();
    void mute();

private:
    QMediaPlayer* player;
    QVideoWidget* videoWidget;
    QMediaPlaylist* playlist;
    Ui::VideoPlayer *ui;
    bool isPlay_wm=false;
    bool ismute=false;
    int   moved;

};

#endif // VIDEOPLAYER_H

videoplayer.cpp代碼以下:ui

#include "videoplayer.h"
#include "ui_videoplayer.h"
#include <QDebug>
#include <QFile>
#include <QCloseEvent>

VideoPlayer::VideoPlayer(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::VideoPlayer)
{
    ui->setupUi(this);
    qDebug()<<"執行到此處";
    connect(ui->Buttonstart,&QPushButton::clicked,this,&VideoPlayer::changestartbutton);
    connect(ui->Buttonmute,&QPushButton::clicked,this,&VideoPlayer::mute);
    init();
    connect(ui->Buttonstart,&QPushButton::clicked,this,&VideoPlayer::slotButtonStart);
    connect(ui->voiceSlider, SIGNAL(sliderMoved(int)), this, SLOT(volumChange(int)));
    connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChange(qint64)));
    connect(ui->timeSlider,SIGNAL(sliderMoved(int)),this,SLOT(seekChange(int)));
    connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(videoTime()));
}

VideoPlayer::~VideoPlayer()
{
    slotstop();
    delete ui;
}

void VideoPlayer::init(){
    //widget=new QWidget;
    button_style();
    player= new QMediaPlayer;
    videoWidget=new QVideoWidget;
    playlist=new QMediaPlaylist;
    playlist->clear();
    playlist->addMedia(QUrl::fromLocalFile("C:\\Users\\44637\\Music\\MV\\陳奕迅-咱們MV.mp4"));
    player->setPlaylist(playlist);

    QFile file("C:\\Users\\44637\\Music\\MV\\陳奕迅-咱們MV.mp4");
    if(!file.open(QIODevice::ReadOnly))
        qDebug() << "Could not open file";

    player->setVideoOutput(videoWidget);
    player->setPlaylist(playlist);
    videoWidget->setAutoFillBackground(true);
    QPalette qplte;
    qplte.setColor(QPalette::Window, QColor(0,0,0));
    videoWidget->setPalette(qplte);
    ui->verticalLayout->addWidget(videoWidget);
    player->play();
    isPlay_wm=true;
}

void VideoPlayer::slotButtonStart(){

    if(!isPlay_wm){
        isPlay_wm=true;
        //Player->setVolume(100);
        player->play();
        //musicTime();
        //qApp->quit();

    }
    else{
        isPlay_wm=false;
        player->pause();
        //musicTime();
    }

}

void VideoPlayer::slotstop(){
    player->stop();
    playlist->clear();
    //player->
}

void VideoPlayer::closeEvent(QCloseEvent *event){
    slotstop();
    event->accept();
}

void VideoPlayer::volumChange(int vol)
{
    player -> setVolume(vol);
}

void VideoPlayer::positionChange(qint64 position)
{
    ui->timeSlider->setMaximum(player->duration() / 1000);//設置滑塊的長度範圍爲音樂長.00度
    ui->timeSlider->setValue(position / 1000);//若是音樂進度改變,則改變滑塊顯示位置
    moved = position;//讓播放時間等於音樂進度(毫秒)
    QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//設置時間
    ui->currenttime ->setText(moveTime.toString("mm:ss"));//顯示時間
    QString t=moveTime.toString("mm:ss");
    QString mm = t.mid(0,2);
    QString ss = t.mid(3, 2);
    int m = mm.toInt();
    int s = ss.toInt();
    int time = m*60*1000 + s*1000;
    qDebug()<<"int"<<time;
}

void VideoPlayer::seekChange(int position)
{
    player -> setPosition(position * 1000);//若是滑塊改變位置,則改變音樂進度
    moved = position * 1000;//讓播放時間等於音樂進度(毫秒)
    QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//設置時間
}

void VideoPlayer::videoTime(){

                qint64 time = player->duration();
                QTime Time(0,(time % (1000 * 60 * 60)) / (1000 * 60),(time % (1000 * 60)) / 1000);
                    ui->videotime->setText(Time.toString("mm:ss"));
                qDebug()<<"time:"<<Time;
}


void VideoPlayer::changestartbutton(){
    if(!isPlay_wm)
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));
    else
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));
}

void VideoPlayer::button_style(){
    ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));
}

void VideoPlayer::mute(){
    if(!ismute){
    player -> setVolume(0);
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\mute.png"));
    ismute=true;
    }
    else{
    player -> setVolume(100);
    ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));
    ismute=false;
    }
}

整體運行界面以下:
在這裏插入圖片描述
在這裏插入圖片描述
一些關鍵方法和思路:
(1)導入歌曲:
從本地文件將歌曲名和歌曲的歌詞導入,獲取文件路徑下全部的音樂文件和歌詞文件,生成兩個QStringList類型的列表。同時將歌名添加到顯示歌名的組件上。同時實例化播放器和播放列表,將列表逐項加載到播放列表上,並將播放列表加載到播放器上。
(2)音樂、視頻進度條:
設置滑塊的長度範圍爲音樂長0.001倍,若是音樂進度發生改變,則同時改變滑塊位置,若是滑塊改變位置,則改變音樂進度。同時設置時間,讓播放時間等於音樂進度(毫秒)並用Qlabel組件顯示。
(3)顯示歌詞:(我的以爲這是個最難的點,參考了大神的思路,加上本身的思考,搞了很久才搞出來😂)
mp3歌詞文件是以lrc爲擴展名的文件,屬於純文本格式文件,經過解析mp3純文本格式的歌詞文件(「XXX.lrc」),實現歌詞的同步顯示。
LRC歌詞是一種包含着「[:]」形式的「標籤(tag)」、基於純文本的歌詞專用格式。
標籤分爲「標識標籤」和「時間標籤」兩種,下面①~⑤爲「標識標籤」,⑥爲「時間標籤」。
①[ti:曲名]
②[ar:藝人名]
③[al:專輯名]
④[by:編者(指編輯LRC歌詞的人)]
⑤[offset:時間補償值] 其單位是毫秒,正值表示總體提早,負值相反。用於整體調整顯示的快慢。
⑥[分:秒.釐秒]歌詞內容
中括號裏邊是歌曲內容顯示時的開始時間,「:」前面爲分鐘,「:」後面爲秒,其中「.」前面爲秒,「.」後面爲釐秒(一秒的百分之一);中括號外邊是歌詞內容。
讀取對應音樂名字的歌詞文件,逐行讀取歌詞,用QMap格式儲存,不一樣標籤開頭用不一樣的key值儲存。
獲取每一個標籤中的時間,將時間和相對應的歌詞以鍵值對的形式儲存到QMap中。
顯示歌詞將當前時間以參數的形式傳入,將時間對應的值讀出。




















this

本人初學QT,已是盡力了,但還有不少作很差的地方,還有一些方法和思路以後再補充。
播放視頻貌似還有點bug,界面太醜,歌詞沒實現滾動,只能顯示當前播放到的歌詞,但願你們討論指導。😁
spa

相關文章
相關標籤/搜索