用Qt调用mplayer实现网易云音乐播放界面,并在开发板上运行

- 最近在学Qt,想起以前做项目的时候基本上都不会写,我怕未来忘记自己做过些什么了!所以总觉得写下来好一点,用于改进自己的开发思路。

1、确定项目需求,界面设计
我喜欢上来确定项目需求,功能设计!向以前写作文一样,总觉得第一感觉是最稳的。但是这样的坏处是考虑不周,长时间停留在计划上。
需求分析:

- 显示歌词
- 暂停播放
- 上一曲,下一曲
- 显示歌曲进度
- 音量大小

界面设计
大概就是模仿网易云音乐的播放界面。
因为考虑到要烧写到开发板上,开发板屏幕是800*480的,所以就这个尺寸了。

2、 开辟进程


void MainWindow::initProcess()
{
    codec = QTextCodec::codecForName("GBK");

    //创建播放进程
    playProcess = new QProcess(this);
    //关联相关的信号,进程启动成功、出错、有数据可读等
    connect(playProcess,&QProcess::started,this,&MainWindow::onStarted);
    connect(playProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(onError()));
    connect(playProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(onReadD()));
    connect(playProcess,SIGNAL(finished(int)),this,SLOT(onPlayProcessFinished()));
    //程序名称
#ifdef Q_OS_WIN
    program = "C:/MPlayer_Windows/MPlayer_core.exe";
#else
    program = "mplayer";
#endif
    //创建定时器
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&MainWindow::onTimeout);
}

3、文件操作,加载歌词音乐

void MainWindow::loadMusic()
{
    musicPath = "../mp3/";  //定位MP3的位置
    QDir dir(musicPath);    //打开目录
    QStringList filters;    //解析MP3
    filters << "*.wma" << "*.mp3";  //*.wma ??
    playList = dir.entryList(filters);//添加到列表
    qDebug() << playList;
    filters.clear();
    filters << "*.lrc";     //歌词文件?
    lrcList = dir.entryList(filters);
    qDebug() << lrcList;

}

4、播放音乐和歌词

//播放音乐
void MainWindow::playMusic(QString mp3Name)
{
    //将路径与歌曲名联合
    QString absMp3Name = musicPath + mp3Name;
    playProcess->close();
    argList.clear();
    argList << "-slave" << "-quiet" << absMp3Name; //在后台运行
    playProcess->start(program,argList);
    playProcess->write("volume 100 1\n");  //yin liang shezhi

    ui->voiceslider->setValue(100);
    //显示歌词
    showLrc(mp3Name);

}

//显示歌词
void MainWindow::showLrc(QString mp3Name)
{
    mp3Name.chop(3);
    QString lrcName = mp3Name + "lrc";
    qDebug() << "lrc : " << lrcName;
    //迭代器
    QStringList::const_iterator it;
    it = qFind(lrcList,lrcName);
    if(it == lrcList.end())     //没有找到对应的歌词
    {
        //清空列表
        ui->listWidget->clear();
        return ;
    }
    lrcTimeList.clear();    //清空时间列表
    ui->listWidget->clear();
    ui->listWidget->verticalScrollBar()->setSliderPosition(0);
    QString absLrcName = musicPath + lrcName;
    QFile file(absLrcName);
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open lrc error" << file.errorString();
        return ;
    }
    QTextStream in(&file);
    in.setCodec("GBK");
    while(!in.atEnd())
    {
        QString line = in.readLine();
        QRegExp reg("\\[[0-9]{2,2}:[0-9]{2,2}\\.[0-9]{2,2}\\]");
        bool ok = line.contains(reg);
        if(ok)
        {
             //[01:20.31]    01  20  3,精确到百毫秒
            double t = line.mid(1,2).toInt()*60 + line.mid(4,2).toInt() + line.mid(7,1).toDouble()/10;
            lrcTimeList << t;
            line.remove(reg);
            QListWidgetItem *item = new QListWidgetItem(line);
            item->setTextAlignment(Qt::AlignCenter);
            ui->listWidget->addItem(item);
        }
    }


}

详细代码


#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QScrollBar>
#include <QIcon>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),index(0),state(NoState),islove(false),voice(false),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setFixedSize(800,480);    //设置主屏幕大小
    loadMusic();
    initProcess();
    //listwidget 设置
    ui->listWidget->verticalScrollBar()->setValue(10);
    ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    ui->voiceslider->setVisible(false);
    connect(ui->voiceslider,SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int)));

}

MainWindow::~MainWindow()
{
    playProcess->close();
    delete ui;
}

void MainWindow::initProcess()
{
    codec = QTextCodec::codecForName("GBK");

    //创建播放进程
    playProcess = new QProcess(this);
    //关联相关的信号,进程启动成功、出错、有数据可读等
    connect(playProcess,&QProcess::started,this,&MainWindow::onStarted);
    connect(playProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(onError()));
    connect(playProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(onReadD()));
    connect(playProcess,SIGNAL(finished(int)),this,SLOT(onPlayProcessFinished()));
    //程序名称
#ifdef Q_OS_WIN
    program = "C:/MPlayer_Windows/MPlayer_core.exe";
#else
    program = "mplayer";
#endif
    //创建定时器
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&MainWindow::onTimeout);
}

void MainWindow::loadMusic()
{
    musicPath = "../mp3/";  //定位MP3的位置
    QDir dir(musicPath);    //打开目录
    QStringList filters;    //解析MP3
    filters << "*.wma" << "*.mp3";  //*.wma ??
    playList = dir.entryList(filters);//添加到列表
    qDebug() << playList;
    filters.clear();
    filters << "*.lrc";     //歌词文件?
    lrcList = dir.entryList(filters);
    qDebug() << lrcList;

}

//播放音乐
void MainWindow::playMusic(QString mp3Name)
{
    //将路径与歌曲名联合
    QString absMp3Name = musicPath + mp3Name;
    playProcess->close();
    argList.clear();
    argList << "-slave" << "-quiet" << absMp3Name; //在后台运行
    playProcess->start(program,argList);
    playProcess->write("volume 100 1\n");  //yin liang shezhi

    ui->voiceslider->setValue(100);
    //显示歌词
    showLrc(mp3Name);

}

//显示歌词
void MainWindow::showLrc(QString mp3Name)
{
    mp3Name.chop(3);
    QString lrcName = mp3Name + "lrc";
    qDebug() << "lrc : " << lrcName;
    //迭代器
    QStringList::const_iterator it;
    it = qFind(lrcList,lrcName);
    if(it == lrcList.end())     //没有找到对应的歌词
    {
        //清空列表
        ui->listWidget->clear();
        return ;
    }
    lrcTimeList.clear();    //清空时间列表
    ui->listWidget->clear();
    ui->listWidget->verticalScrollBar()->setSliderPosition(0);
    QString absLrcName = musicPath + lrcName;
    QFile file(absLrcName);
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open lrc error" << file.errorString();
        return ;
    }
    QTextStream in(&file);
    in.setCodec("GBK");
    while(!in.atEnd())
    {
        QString line = in.readLine();
        QRegExp reg("\\[[0-9]{2,2}:[0-9]{2,2}\\.[0-9]{2,2}\\]");
        bool ok = line.contains(reg);
        if(ok)
        {
             //[01:20.31]    01  20  3,精确到百毫秒
            double t = line.mid(1,2).toInt()*60 + line.mid(4,2).toInt() + line.mid(7,1).toDouble()/10;
            lrcTimeList << t;
            line.remove(reg);
            QListWidgetItem *item = new QListWidgetItem(line);
            item->setTextAlignment(Qt::AlignCenter);
            ui->listWidget->addItem(item);
        }
    }


}


void MainWindow::on_btn_play_clicked()
{
    if(playList.size() > 0)
    {
        if(state == NoState)
        {
            //qDebug() << "Nostate :" <<state ;
            index = 0;
            playMusic(playList.at(index));
        }
        else if(state == Playing)
        {
            //qDebug() << "playing :" << state ;
            timer->stop();
            state = Pause;
            playProcess->write("pause\n");
            ui->btn_play->setStyleSheet("border-image: url(:/play.png);");
            ui->btn_song->setStyleSheet("border-image: url(:/playmain.png);");

        }
        else if(state == Pause)
        {
            qDebug() << "pause :" <<state ;
            state = Playing;
            playProcess->write("pause\n");
            //ui->btn_play->setText(tr("暂停"));
            ui->btn_play->setStyleSheet("border-image: url(:/stop.png);");
            ui->btn_song->setStyleSheet("border-image: url(:/stopmain.png);");
            timer->start();
        }
    }
}


//启动进程成功
void MainWindow::onStarted()
{
    qDebug("playing~~");
    state = Playing;
    //ui->btn_play->setText(tr("暂停"));
    ui->btn_play->setStyleSheet("border-image: url(:/stop.png);");
    ui->btn_song->setStyleSheet("border-image: url(:/stopmain.png);");
    playProcess->write("get_time_length\n");
    timer->start(40);
}
//错误处理
void MainWindow::onError()
{
    qDebug() << "error : " << playProcess->errorString();
}

void MainWindow::onReadD()
{
    while(playProcess->bytesAvailable())
    {
        QByteArray arr = playProcess->readLine();
        QString str = codec->toUnicode(arr);
        if(str.contains("ANS_LENGTH"))
        {//获取时间总长度
            qDebug() << "::"<<str;
            str.remove("\n");
            str.remove("\r");
            str.remove("ANS_LENGTH=");
            qDebug() << "str = " << str;
            int t = str.toDouble();
            int m = t/60;
            int s = t%60;//Because % is only defined for integer types.
            tlength = m * 60 + s;
            //qDebug() << "tlength:" << tlength;
            QString timeLength;
            timeLength.sprintf("%02d:%02d",m,s);
            ui->label_time_length->setText(timeLength);
        }
        if(str.contains("ANS_TIME_POSITION"))//
        {//获取当前时间
            //qDebug() << "::"<<str;
            str.remove("\n");
            str.remove("\r");
            double t = QString(str.split("=").at(1)).toDouble();
            int index = lrcTimeList.indexOf(t);
            if(index != -1)
            {//根据播放时间,设置当前显示行
                //ui->listWidget->setCurrentRow(index);
                //设置正在播放的歌词字体变大、颜色为红色
                ui->listWidget->item(index)->setFont(QFont(tr("微软雅黑"),12));
                ui->listWidget->item(index)->setTextColor(Qt::white);
                if(index > 1)
                {//上一行改的字体与颜色还原
                    ui->listWidget->item(index-1)->setFont(QFont(tr("微软雅黑"),10));
                    ui->listWidget->item(index-1)->setTextColor(Qt::black);
                }
                if(index >5)
                {//播放到第5行时,移动滚动条位置,使用当前显示的歌词居中显示
                    ui->listWidget->verticalScrollBar()->setSliderPosition(index-5);
                }
            }

            //显示当前时间
            int m = t/60;
            int s = (int)t%60;
            QString timePos;
            timePos.sprintf("%02d:%02d",m,s);

            ui->label_time_now->setText(timePos);
            //qDebug() << "now: " << (m * 60 + s) << "all:" <<tlength;
            int now = (m * 60 + s);
            double slider =  now * 100 / tlength;
            //qDebug() << slider;
            ui->timeSlider->setValue(slider);
        }
    }
}




//定时器超时
void MainWindow::onTimeout()
{
    playProcess->write("get_time_pos\n");
}

void MainWindow::valueChanged(int volumes)
{
    playProcess->write("volume %d 1\n",volumes);
}
//播放进程结束
void MainWindow::onPlayProcessFinished()
{
    qDebug() << "process finished";
    timer->stop();
    state = NoState;
    //ui->btn_play->setText(tr("播放"));
    ui->btn_play->setStyleSheet("border-image: url(:/start.png);");
}

//下一首
void MainWindow::on_btn_next_clicked()
{
    if(index < playList.size()-1)
    {
        index++;
       // QString mp3Name = musicPath + playList.at(index);
        playMusic(playList.at(index));
    }
    else
    {
        return;
    }
}

//上一首
void MainWindow::on_btn_last_clicked()
{
    if(index > 0)
    {
       index--;
      // QString mp3Name = musicPath + playList.at(index);
       playMusic(playList.at(index));
    }
    else
    {
       return;
    }
}

void MainWindow::on_btn_love_clicked()
{
    if(islove == false)
    {
        islove = true;
        ui->btn_love->setStyleSheet("border-image: url(:/islove.png);");
    }
    else
    {
        islove = false;
        ui->btn_love->setStyleSheet("border-image: url(:/nolove.png);");
    }
}

void MainWindow::on_btn_song_clicked()
{
    on_btn_play_clicked();
}

void MainWindow::on_btn_voice_clicked()
{
    if(voice == false)
    {
        voice = true;
        ui->voiceslider->setVisible(true);
    }
    else
    {
        voice = false;
        ui->voiceslider->setVisible(false);
    }
}

最后是效果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值