前言

    最近有一个课程实验,利用window上的API接口实现MP3播放器。 突发奇想,在linux下用相关接口做一个MP3播放器。最先的打算是完全使用纯C写的,但后来感觉编写调试实在费劲。于是就使用了QT这个IDE工具,还可以编写个图形界面的。这篇博客主要贴代码,理论部分,请参见我的另一篇博客(基于QT实现Mp3播放器(理论部分))
    来,小二,上个图(注重逻辑,界面并没有认真规划,⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄)。

实现代码

playerprocess.cpp

#include "playerprocess.h"
#include<QDebug>PlayerProcess::PlayerProcess(QObject *parent) : QObject(parent)
{process = NULL;
}//播放Mp3文件
void PlayerProcess::play(QString mp3_file)
{if(mp3_file.isEmpty() == false){QString play_tool = "mplayer";      //利用mplayer工具进行播放QStringList argus;process = new QProcess();   //每次新生成一个播放进程//以下是播放时的参数argus<<"-slave";argus<<"-quiet";argus<<mp3_file;//开始播放process->start(play_tool,argus);if(process->waitForStarted(5000) == false)       //等待播放进程开始qDebug()<<"fail to pause or replay the player";}elseqDebug()<<"file name is empty!!!";}
//暂停
void PlayerProcess::Pause()
{process->write("pause\n");      //利用mplayer提供的借口,向进程写入参数
}
//重新开始
void PlayerProcess::Rebegin()
{process->write("pause\n");   //利用mplayer提供的借口,向进程写入参数
}//加音量:
void PlayerProcess::Up(int volume)
{QString cmd = "volume " + QString::number(volume)+" 2 \n";  //利用mplayer提供的借口,向进程写入参数process->write(cmd.toUtf8());
}//减音量
void PlayerProcess::Down(int volume)
{QString cmd = "volume " + QString::number(volume)+" 2 \n";  //利用mplayer提供的借口,向进程写入参数process->write(cmd.toUtf8());
}//结束当前播放进程
void PlayerProcess::End()
{if(process != NULL)      //判断是否是自动播放完毕停止,还是手动更换曲目停止{QStringList args;process->kill();             //kill 当前进程if(process->waitForFinished(5000) == false)           //等待进程结束{qDebug()<<"fail to kill the last song";}else{delete process;qDebug()<<"kill the last song";}}}//获取播放进程
QProcess* PlayerProcess::GetProcess()
{return process;
}//设置播放进程
void PlayerProcess::SetProcess(QProcess * process)
{this->process = process;
}

player.cpp

#include "player.h"#include <QDebug>Player::Player(QObject *parent) : QObject(parent)
{volume = 50;        //初始化音量为50.音量范围为0-100status = Player::InitStatus ;         //初始化状态cur_song = -2;      //init status
}PlayerProcess* Player::GetPlaPro()
{return &playerprocess;
}//返回当前播放器状态
Player::PlayStatus Player::GetPlaySta()
{return status;
}//判断一个状态是否正常定义(仅限枚举变量底层用连续int实现)
bool Player::IsIncInPlaySta(PlayStatus sta)
{if(sta >= Player::InitStatus && sta<= Player::PauseStatus )return true;elsereturn false;
}//设置播放器状态
void Player::SetPlaySta(PlayStatus sta)
{if(IsIncInPlaySta(sta))status = sta;elseqDebug()<<"player status is invalid";
}//设置当前歌曲
void Player::SetCurSong(int index)
{if(index >= -1 && index <= song_list.size())        //-1代表下一次播放从最后一首开始。song_lise.size()代表下一次播放从头开始cur_song = index;elseqDebug()<<"player index is invalid";
}//获得播放器歌曲
int Player::GetCurSong()
{return cur_song;
}//设置歌曲列表
void Player::SetSongList(QStringList list)
{if(list.empty() == false)song_list = list;
}//添加歌曲到列表
void Player::AddSongToList(QStringList add_songs)
{if(add_songs.empty() == false)song_list.append(add_songs);
}//获取歌曲列表
QStringList Player::GetSongList()
{return song_list;
}//删除歌曲
void Player::DelSong(int index)
{if(index >= 0 && index <= song_list.size()-1){song_list.removeAt(cur_song);}
}//删除当前歌曲
void Player::DelCurSong()
{DelSong(cur_song);
}//加音量
void Player::Up()
{if(volume < 100){volume+=10;playerprocess.Up(volume);}}
//减音量
void Player::Down()
{if(volume > 0){volume-=10;playerprocess.Down(volume);}
}//重新开始一个播放
void Player::NewPlay()
{if(song_list.size() == 0)        //若歌曲列表为空{qDebug()<<"song list is empty";return ;}else{if(cur_song == -1)       //若是第一首(0开始)以前的歌曲,就循环到歌曲列表的最后一首cur_song = song_list.size()-1;else if(cur_song == -2 || cur_song == song_list.size())      //若是超过最后一首,则回到第一首(0开始)cur_song = 0;}QString play_song = song_list.at(cur_song);   //获得歌曲列表内容playerprocess.play(play_song);         //播放}//播放歌曲
void Player::Play()
{if(status == Player::InitStatus)      //初始状态{NewPlay();          //一个新的播放任务开始status = Player::RunningStatus;  //设置为运行状态}else if(status == Player::RunningStatus)      //若是运行状态{playerprocess.Pause();           //暂停status = Player::PauseStatus;  //设置为运行状态}else{playerprocess.Rebegin();       //重新开始status = Player::RunningStatus; //设置为运行状态}}//下一曲
void Player::Next()
{if(cur_song == -2)      //init statuscur_song = 0;else++cur_song;}// 上一曲
void Player::Pre()
{if(cur_song == -2)      //init statuscur_song = 0;else--cur_song;}//kill当前播放进程
void Player::End()
{playerprocess.End();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"#include<QFileDialog>
#include<QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);InitWindow();       //初始化窗口
}Widget::~Widget()
{delete ui;
}//初始化窗口:大小、颜色、背景等
void Widget::InitWindow()
{setWindowTitle("EasyMp3Player");setFixedSize(this->width(),this->height());//设置背景QPalette PAllbackground = this->palette();QImage ImgAllbackground(":/back.png");QImage fitimgpic=ImgAllbackground.scaled(this->width(),this->height(), Qt::IgnoreAspectRatio);PAllbackground.setBrush(QPalette::Window, QBrush(fitimgpic));this->setPalette(PAllbackground);QFont item_font;item_font.setPixelSize(50);item_font.setBold(true);ui->listWidget->setStyleSheet("background-color:transparent; QListWidget::item(color:black)");
}//高亮选中的歌曲栏目
void Widget::HighLigCurSong()
{int cur_song = player.GetCurSong() ;QStringList song_list = player.GetSongList();if(cur_song>=0 && cur_song <= song_list.size()-1){QListWidgetItem * tmp =  ui->listWidget->item(cur_song);tmp->setBackgroundColor(QColor("orange"));        //当前播放歌曲高亮}}//显示歌曲列表
void Widget::ShowSongList()
{ui->listWidget->clear();QStringList songs;QStringList song_list = player.GetSongList();foreach (QString song_dir, song_list){songs.append(QFileInfo(song_dir).fileName());}ui->listWidget->addItems(songs);HighLigCurSong();   //高亮}//点击播放按钮
void Widget::on_pushButton_play_clicked()
{Player::PlayStatus status = player.GetPlaySta();player.Play();  //播放歌曲if(status == Player::InitStatus)ConnectNewProcess();        //连接新的player进程到自动播放结束槽//关联每个播放进程结束信号和槽ShowSongList();          //在QListWidget中显示歌曲列表}//下一曲
void Widget::on_pushButton_next_clicked()
{Player::PlayStatus status = player.GetPlaySta();if(status == Player::RunningStatus)player.End();player.Next();       //下一曲player.SetPlaySta(Player::InitStatus);  //回到初始状态on_pushButton_play_clicked();}//上一曲
void Widget::on_pushButton_pre_clicked()
{Player::PlayStatus status = player.GetPlaySta();if(status == Player::RunningStatus)     //是否是从运行状态点击上一曲player.End();player.SetPlaySta(Player::InitStatus);      //回到初始状态player.Pre();        //上一曲on_pushButton_play_clicked();}//添加歌曲到播放列表
void Widget::on_pushButton_Add_clicked()
{QStringList file_names = QFileDialog::getOpenFileNames(this,tr("choose a song"),".","music(*.mp3)");player.AddSongToList(file_names);ShowSongList();         //show song list
}//删除当前歌曲
void Widget::on_pushButton_del_clicked()
{player.DelCurSong();        //删除当前歌曲ShowSongList();player.End();       //结束当前播放歌曲player.SetPlaySta(Player::InitStatus);on_pushButton_play_clicked();}//加音量
void Widget::on_pushButton_up_clicked()
{player.Up();
}//减音量
void Widget::on_pushButton_down_clicked()
{player.Down();
}//连接新的player进程到自动播放结束槽
bool Widget::ConnectNewProcess()
{QProcess * tmp = player.GetPlaPro()->GetProcess();if(tmp != NULL){connect(tmp ,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(PlayEnd(int,QProcess::ExitStatus)));return true;}else{qDebug()<<"connect new player process failed";return false;}
}//一首歌曲自动播放结束
void Widget::PlayEnd(int code, QProcess::ExitStatus exit_status)
{if(exit_status == QProcess::NormalExit)     //正常退出(注意:切换下一曲、上一曲为播放进程为非正常退出){player.GetPlaPro()->SetProcess(NULL);   //设置为空on_pushButton_next_clicked();       //下一曲ShowSongList();     //显示列表}}//程序退出,把所有的播放进程删除
void Widget::closeEvent(QCloseEvent *event)
{player.End();
}//退出
void Widget::on_pushButton_Quit_clicked()
{close();
}

   具体的代码都比较简单,注释也相对详细。这里只说一个点(不关心的可以略过)。如下
当前歌曲播放完毕之后需要切换下一首,因为是每次使用QProcess新进程播放音乐,所以主进程和播放的进程相对独立,这样的话就必须在新建QProcess进程时connect播放进程的退出状态到具体的槽(在这个槽中进行新建下一个播放进程,否则达不到自动切换的目的,同时也为了更改(高亮)下一首歌曲)。
问题是如果使用上述分层的设计按理说,这部分connect的代码应该放在player这层中,但是player是做为一个widget的一个对象,这样的话,就没法调用包括ShowSongList()的槽。 这个问题想了很久,尝试了很多方法,还是不太满意。最后只能把connect连接放在widget中实现了。

后言

具体的工程代码已经打包了,有需要的请到对应的资源页进行下载。

基于QT实现Mp3播放器(代码部分)相关推荐

  1. 基于QT实现Mp3播放器(理论论述部分)

    前言     最近有一个课程实验,利用window上的API接口实现MP3播放器. 突发奇想,在linux下用相关接口做一个MP3播放器.最先的打算是完全使用纯C写的,但后来感觉编写调试实在费劲.于是 ...

  2. 基于QT的mp3播放器设计

    1.首先在ui中画出两个新建项,分别命名为OpenAction和DeleteAction,并拖到头部. 2. 选择转到槽. 3.选择table weight 4.选择转到槽里的double 5.mai ...

  3. alin的学习之路:嵌入式课程设计总结(基于Linux的Qt版MP3播放器)

    嵌入式课程设计总结(基于Linux的Qt版MP3播放器) 废话不多写直接上图上代码,其中有很多不规范的地方,希望大佬们指正. 1.课设题目 设计一个MP3播放器,要求:使用Linux下的madplay ...

  4. 基于Qt的音乐播放器制作

    基于Qt的音乐播放器制作 使用浏览器自带工具抓包歌曲资源 开发人员工具抓包 点击浏览器右上角的 "-" 快捷键(Alt + F): 点击其中的"更多工具" ➡ ...

  5. 基于python的音频播放器_基于python实现音乐播放器代码实例

    基于python实现音乐播放器代码实例,一首,函数,按钮,布局,音乐 基于python实现音乐播放器代码实例 易采站长站,站长之家为您整理了基于python实现音乐播放器代码实例的相关内容. 核心播放 ...

  6. 基于Qt的音乐播放器(二)切换歌曲,调节音量,调节语速,暂停

    2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票! 我的投票地址:点击为我投票 文章目录 1.切换歌曲 2.调节音量 3.调节语速 4.播放/暂停 5.我们来看下效果 6.关于上一篇提 ...

  7. jQuery+html5音乐网站mp3播放器代码

    播放器演示 jQuery+html5音乐网站mp3播放器代码演示 播放器介绍 jQuery+html5音乐网站mp3播放器代码 1. 支持显示播放进度条: 2. 支持拖动播放功能: 3. 支持显示音量 ...

  8. 基于SDL的mp3播放器

    基于SDL的mp3播放器 SDL虽然本身提供播放音乐都功能但是不好用,SDL_mixer为SDL提供了快捷的音乐播放功能.但是SDL_mixer本身只能播放wav格式的音乐,并不能播放mp3,为了能完 ...

  9. 基于Stm32的MP3播放器设计与实现

    原创博文,转载请注明出处 这是我高级电子技术试验课做的作业,拿来共享一下.项目在安福莱例程基础之上进行的功能完善,里面的部分内容可参考安福莱mp3例程.当然用的板子也是安福莱的板子,因为算起来总共做了 ...

最新文章

  1. 记一次关于mock Systemc.currentTimeMillis的实践
  2. C#类的属性遍历及属性值获取
  3. 基于小样本学习的图像分类技术综述
  4. Mybatis源码之与Spring集成包
  5. Asp.net的生命周期之应用程序生命周期
  6. Linux高级实用命令
  7. bzoj 3388: [Usaco2004 Dec]Cow Ski Area雪场缆车(Tarjan)
  8. 解决VS2017安装一直卡在正在下载
  9. python量化投资推荐书籍_有没有值得推荐的介绍有名的量化投资策略的书籍?
  10. 91m2中对DB进行了一次封装的DBHelpUtil工具类
  11. 习题 9.9 商店销售某一商品,商店每天公布统一的折扣(discount)。同时允许销售人员在销售时灵活掌握售价(price),在此基础上,对一次购10件以上者,还可以享受9.8折优惠。
  12. 信源编码作业(1)——绘制并分析清浊音频谱图
  13. 一个使用 selenium 模块爬取(Twitter、New York Times)网站的可配置爬虫代码
  14. 那些年啊 那些事 一个程序员的奋斗史 121
  15. P2P大潮正在消退,第一梯队亦需自危
  16. fusion 360 手指虎建模
  17. tensorflow one-hot独热编码
  18. operation 04
  19. 电脑维修工具 硬盘检测工具 查查是否有坏道
  20. 2020 CCF BDCI 非结构化商业文本信息中隐私信息识别TOP5方案

热门文章

  1. 王道计算机网络知识点整理
  2. 请给出计算231-1的python表达式_计算 2 31 -1 的 Python 表达式是 。_学小易找答案
  3. 《电路基础》同相运算放大器
  4. angularJS的复选框
  5. 程序员7年和我的7点感想――我的程序人生
  6. 使用 Windows Virtual PC 创建一个虚拟机
  7. 新书介绍:iPhoneiPad企业移动应用开发秘籍
  8. C语言综合练习5:快译通下
  9. 浴谷P1540 机器翻译
  10. 重学《动手学深度学习》 —— 深度学习简介(第一章)笔记