QT音频播放器
最近學的QT,如果程序中有不規范的地方請多多包涵
項目功能:播放歌曲 ,播放視頻,上一曲,下一曲,雙擊歌曲直接播放,循環播放,單曲循環,隨機播放,音量調節,添加本地歌曲,把視頻或音樂拖到窗口直接播放,拖動進度條,刪除歌曲。
本程序支持的歌曲或視頻類型:list << "*.mp3" << "*.wav" << "*.wma" << "*.flac" << "*.wmv" << "*.mp4" << "*.mov" << "*.avi" (如果需要播放其他類型的,需要添加對應類型后綴)
部分類型是播放不了的,需要安裝解碼器,下面是其他兩位博主的方法
參考鏈接:https://blog.csdn.net/mmmmmmyy/article/details/81877233?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163972446016780271540688%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163972446016780271540688&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-81877233.pc_search_mgc_flag&utm_term=DirectShowPlayerService%3A%3AdoRender%3A+Unresolved+error+code+80040266&spm=1018.2226.3001.4187https://blog.csdn.net/mmmmmmyy/article/details/81877233?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163972446016780271540688%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163972446016780271540688&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-81877233.pc_search_mgc_flag&utm_term=DirectShowPlayerService%3A%3AdoRender%3A+Unresolved+error+code+80040266&spm=1018.2226.3001.4187參考鏈接:https://blog.csdn.net/qq_41071706/article/details/89855986?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163972446016780271540688%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163972446016780271540688&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-89855986.pc_search_mgc_flag&utm_term=DirectShowPlayerService%3A%3AdoRender%3A+Unresolved+error+code+80040266&spm=1018.2226.3001.4187https://blog.csdn.net/qq_41071706/article/details/89855986?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163972446016780271540688%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163972446016780271540688&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-89855986.pc_search_mgc_flag&utm_term=DirectShowPlayerService%3A%3AdoRender%3A+Unresolved+error+code+80040266&spm=1018.2226.3001.4187
播放歌曲界面
播放視頻界面(雙擊播放界面可以窗口最大化)
程序部分:
構造函數和文件獲取部分
AudioPlay::AudioPlay(QWidget *parent) :QMainWindow(parent),ui(new Ui::AudioPlay) {ui->setupUi(this);player = new QMediaPlayer;playerList = new QMediaPlaylist;videoPlayWidget = new videowidget;// 在當前路徑創建一個文件(文件名PlayList.ini)把讀到的歌曲輸出到里面,方便下一次播放configIniWrite = new QSettings("PlayList.ini", QSettings::IniFormat);playerIndex = 0;playerPrevious = 0;playerMode = 0;player->setVolume(50); // 設置初始音量ui->Slider_Volume->setValue(50);ui->label_Volume->setText("50%");playerList->setPlaybackMode(QMediaPlaylist::Loop); // 循環播放模式// 允許文件拖拽到窗口部分this->setAcceptDrops(true);mLocation = this->geometry();mIsMax = false;mDrag = false;//// 手動添加窗口頂部處理部分this->installEventFilter(this); // 事件過濾器就是接收所有被發送到這個對象的事件的對象ui->pushButton_WindowMin->setIcon(QIcon(":/image/jianhao.png"));ui->pushButton_WindowMin->setIconSize(QSize(16,16));ui->pushButton_WindowMax->setIcon(QIcon(":/image/fangkuang.png"));ui->pushButton_WindowMin->setIconSize(QSize(16,16));ui->pushButton_WindowExit->setIcon(QIcon(":/image/guanbi.png"));ui->pushButton_WindowMin->setIconSize(QSize(16,16));ui->pushButton_WindowMin->setFlat(true);ui->pushButton_WindowMin->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->pushButton_WindowMax->setFlat(true);ui->pushButton_WindowMax->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->pushButton_WindowExit->setFlat(true);ui->pushButton_WindowExit->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->tableWidget->setShowGrid(false);//隱藏表格線setStyleSheet("QMainWindow{color:#E8E8E8;background:#43CD80;}"); // //另外在設計器內查看widgetTitle樣式,內有標題欄各個子控件的樣式設置// // 設置窗口名稱,圖標this->setWindowTitle(QTextCodec::codecForName("GBK")->toUnicode("音頻播放器"));this->setWindowIcon(QIcon(":/image/icon.png"));QPixmap *pixmap = new QPixmap(":/image/icon.png");pixmap->scaled(ui->logo->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);ui->logo->setScaledContents(true);ui->logo->setPixmap(*pixmap);ui->label_Title->setText(QTextCodec::codecForName("GBK")->toUnicode("音頻播放器"));// 設置背景圖片為bj.jpgthis->setObjectName("mainWindow");this->setStyleSheet("#mainWindow{border-image:url(:/image/bj.png);}");this->setWindowFlags(Qt::FramelessWindowHint);//無邊框 // this->setAttribute(Qt::WA_TranslucentBackground);//背景透明// this->setWindowFlags(Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);// 設置按鍵圖標ui->PushButton_PlayStop->setIcon(QIcon(":/image/bofang.png"));ui->PushButton_PlayStop->setIconSize(QSize(48,48));ui->PushButton_PlayMode->setIcon(QIcon(":/image/yinlebofangye-xunhuanbofang.png"));ui->PushButton_PlayMode->setIconSize(QSize(48,48));ui->PushButton_Previous->setIcon(QIcon(":/image/shangyishou.png"));ui->PushButton_Previous->setIconSize(QSize(48,48));ui->PushButton_Next->setIcon(QIcon(":/image/xiayishou.png"));ui->PushButton_Next->setIconSize(QSize(48,48));ui->PushButton_OpenFile->setIcon(QIcon(":/image/tianjiagequ.png"));ui->PushButton_OpenFile->setIconSize(QSize(48,48));ui->PushButton_DeleteMusic->setIcon(QIcon(":/image/shanchu.png"));ui->PushButton_DeleteMusic->setIconSize(QSize(48,48));QPixmap *pixmap1 = new QPixmap(":/image/jurassic.png");pixmap->scaled(QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation);ui->label_Volume_2->setScaledContents(true);ui->label_Volume_2->setPixmap(*pixmap1);// 設置圖標為透明ui->PushButton_PlayStop->setFlat(true);ui->PushButton_PlayStop->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->PushButton_PlayMode->setFlat(true);ui->PushButton_PlayMode->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->PushButton_Previous->setFlat(true);ui->PushButton_Previous->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->PushButton_Next->setFlat(true);ui->PushButton_Next->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->PushButton_OpenFile->setFlat(true);ui->PushButton_OpenFile->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->PushButton_DeleteMusic->setFlat(true);ui->PushButton_DeleteMusic->setStyleSheet("QPushButton{border:none;background:transparent;}");ui->label_Volume->setStyleSheet("QLabel{border:none;background:transparent;}");ui->label_MusicTime->setStyleSheet("QLabel{border:none;background:transparent;}");ui->label_PlayTime->setStyleSheet("QLabel{border:none;background:transparent;}");ui->Slider_Volume->setStyleSheet("QSlider{border:none;background:transparent;}");ui->Slider_ProgressBar->setStyleSheet("QSlider{border:none;background:transparent;}");ui->label_Volume_2->setStyleSheet("QLabel{border:none;background:transparent;}");ui->tableWidget->verticalHeader()->setHidden(true);ui->tableWidget->setStyleSheet("QTableView::item:selected{color:black;background:black;}");ui->tableWidget->setStyleSheet("QTableWidget{border:none;background:transparent;}");//設置歌曲列表控件的透明度// ui->label_Volume->setStyleSheet(QString("color:rgba(255,255,255,255);background-color:rgba(10,10,10,150)"));//設置歌詞列表控件的透明度// ui->tableWidget->setStyleSheet(QString("color:rgba(255,255,255,255);background-color:rgba(10,10,10,200)"));// setWindowFlags(Qt::FramelessWindowHint); // 無邊框// 播放測試 // player->setMedia(QUrl::fromLocalFile("C:\\Users\\71780\\Desktop\\MUSIC\\劉德華 - 暗里著迷.wav")); // player->setPlaylist(); // player->setVolume(50); // player->play();// searchMusic("C:\\Users\\71780\\Desktop\\MUSIC");// 讀取配置文件的內容:歌曲名 把前一次寫入的歌曲讀出來configIniRead = new QSettings("PlayList.ini", QSettings::IniFormat);for(int i=0; ; ++i) // 將所有的播放列表顯示在列表控件中{if(configIniRead->value("/song/"+QString::number(i),100).toInt()!=100){QString path = configIniRead->value("/song/"+QString::number(i)).toString();playerList->addMedia(QUrl::fromLocalFile(path));QFileInfo fileInfo;fileInfo = QFileInfo(path);QString fileName = fileInfo.completeBaseName(); // 文件名不帶后綴QString fileSuffix = fileInfo.suffix(); // 文件后綴int rownum=ui->tableWidget->rowCount();ui->tableWidget->insertRow(rownum);ui->tableWidget->setItem(rownum, 0, new QTableWidgetItem(fileName + "." + fileSuffix));}else{break;}}player->setPlaylist(playerList); // 把播放列表添加到播放器playerList->setCurrentIndex(0); }AudioPlay::~AudioPlay() {delete ui; }void AudioPlay::searchMusic(QString dirPath) {QList<QString> findedFilePath;QStringList list;bool status = false;// playerList->clear(); //清除播放列表list << "*.mp3" << "*.wav" << "*.wma" << "*.flac" << "*.wmv" << "*.mp4" << "*.mov" << "*.avi" ;findFormat(dirPath, list, findedFilePath);foreach(QString music, findedFilePath){QFileInfo fileInfo;fileInfo = QFileInfo(music); QString fileName = fileInfo.completeBaseName(); // 文件名不帶后綴QString fileSuffix = fileInfo.suffix(); // 文件后綴qDebug() << fileInfo;if(playerList->mediaCount() > 0){for (int i = 0;i < playerList->mediaCount() ; i++){QString songName = ui->tableWidget->item(i,0)->text(); // 取出字符串if(songName == fileName + "." + fileSuffix) // 判斷是否是重復添加歌曲{status = true;break;}}}if(status == false){playerList->addMedia(QUrl(music)); // 把掃描得到的歌曲添加到播放列表上。帶路徑的int rownum = ui->tableWidget->rowCount();ui->tableWidget->insertRow(rownum);ui->tableWidget->setItem(rownum, 0, new QTableWidgetItem(fileName + "." + fileSuffix));configIniWrite->setValue("/song/"+QString::number(rownum), music); // 保存歌曲列表}status = false;}player->setPlaylist(playerList); // 把播放列表添加到播放器 }// 打開文件 void AudioPlay::on_PushButton_OpenFile_clicked() {QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),"./",QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);searchMusic(dir); }void AudioPlay::findFormat(QString &path, QStringList format, QList<QString>& receiveFilePath) {// 判斷路徑是否存在QDir dir(path);if(!dir.exists()) return;// 定義迭代器并設置過濾器QDirIterator dirIterator(path, format, QDir::Files | QDir::NoSymLinks,QDirIterator::Subdirectories);while(dirIterator.hasNext()){dirIterator.next();receiveFilePath.append(dirIterator.fileInfo().absoluteFilePath());} }基本的按鍵槽函數
// 播放音樂 void AudioPlay::playMusic(int index) {if(playerList->mediaCount() == 0){QMessageBox QmgBox;QMessageBox::warning(this,QTextCodec::codecForName("GBK")->toUnicode("錯誤"),QTextCodec::codecForName("GBK")->toUnicode("播放列表為空,請先添加音頻"));return;}videoPlayWidget->close();if(index < 0){index = playerList->mediaCount() - 1; // 計算播放列表文件數}if(index > playerList->mediaCount() - 1){index = 0;}connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(do_getduration_slots(qint64))); // 獲取歌曲時間總長,信號與槽connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(do_updatePosition_slots(qint64))); // 獲取當前播放進度,信號與槽ui->PushButton_PlayStop->setIcon(QIcon(":/image/zanting-xian.png"));ui->PushButton_PlayStop->setIconSize(QSize(48,48));if(playerPrevious != index) // 判斷是否是上一首歌曲{playerList->setCurrentIndex(index);}else // 繼續播放上一首歌曲{do_getduration_slots(0);}// 判斷是否是視頻 //"*.mp4" << "*.mov" << "*.aviif(ui->tableWidget->item(index,0)->text().right(3) == "wmv" ||ui->tableWidget->item(index,0)->text().right(3) == "mp4" ||ui->tableWidget->item(index,0)->text().right(3) == "mov" ||ui->tableWidget->item(index,0)->text().right(3) == "avi" ){ui->horizontalLayout_4->addWidget(videoPlayWidget);player->setVideoOutput(videoPlayWidget);videoPlayWidget->show();player->play();}player->play(); }播放處理函數?
// 播放和停止槽函數 void AudioPlay::on_PushButton_PlayStop_clicked() {if(player->state() == QMediaPlayer::PlayingState) // 判斷當前播放狀態{player->pause();ui->PushButton_PlayStop->setIcon(QIcon(":/image/bofang.png"));ui->PushButton_PlayStop->setIconSize(QSize(48,48));}else{playMusic(playerList->currentIndex());} }// 上一曲 void AudioPlay::on_PushButton_Previous_clicked() {playerIndex = playerList->currentIndex() - 1;playMusic(playerIndex); }// 下一曲 void AudioPlay::on_PushButton_Next_clicked() {playerIndex = playerList->currentIndex() + 1;playMusic(playerIndex); }// 設置音量 void AudioPlay::on_Slider_Volume_valueChanged(int value) {player->setVolume(value);ui->label_Volume->setText(QString::number(value)+"%"); }進度條和歌曲(視頻)時間顯示部分?
// 獲取歌曲時長,歌曲改變時才會執行這個槽函數 void AudioPlay::do_getduration_slots(qint64 playtime) {qDebug() << __FUNCTION__;playtime = player->duration(); // 獲取時間GetTime(playtime);ui->Slider_ProgressBar->setRange(0,playtime); // 根據播放時長來設置滑塊的范圍ui->Slider_ProgressBar->setEnabled(playtime > 0);ui->Slider_ProgressBar->setPageStep(playtime / 10); // 以及每一步的步數// 前一首設置為黑色QTableWidgetItem *FileName1 = new QTableWidgetItem(ui->tableWidget->item(playerPrevious,0)->text());FileName1->setTextColor(QColor(Qt::black));ui->tableWidget->setItem(playerPrevious,0,FileName1);// 當前設置為藍綠色QTableWidgetItem *FileName = new QTableWidgetItem(ui->tableWidget->item(playerList->currentIndex(),0)->text());FileName->setTextColor(QColor(Qt::cyan));ui->tableWidget->setItem(playerList->currentIndex(),0,FileName);playerPrevious = playerList->currentIndex(); }// 計算時間 void AudioPlay::GetTime(qint64 playtime) {int h,m,s;playtime /= 1000; //獲得的時間是以毫秒為單位的h = playtime/3600;m = (playtime-h*3600)/60;s = playtime-h*3600-m*60;ui->label_MusicTime->setText(QString("%1:%2:%3").arg(h,2,10,QLatin1Char('0')).arg(m,2,10,QLatin1Char('0')).arg(s,2,10,QLatin1Char('0'))); // 把int型轉化為string類型后再設置為label的text /* ui->label_MusicTime->setStyleSheet("color:white"); */ // 設置字體顏色為白色}// 接收歌曲位置改變,改變進度條 void AudioPlay::do_updatePosition_slots(qint64 position) {int h,m,s;ui->Slider_ProgressBar->setValue(position);//設置滑塊位置position /= 1000; //獲得的時間是以毫秒為單位的h = position/3600;m = (position-h*3600)/60;s = position-h*3600-m*60;// arg(整數類型,補位數,進制,補位字符);ui->label_PlayTime->setText(QString("%1:%2:%3").arg(h,2,10,QLatin1Char('0')).arg(m,2,10,QLatin1Char('0')).arg(s,2,10,QLatin1Char('0'))); // 把int型轉化為string類型后再設置為label的text }刪除和拖拽部分?
// 拖動進度松手槽函數 void AudioPlay::on_Slider_ProgressBar_sliderReleased() { // qDebug() << __FUNCTION__;player->setPosition(ui->Slider_ProgressBar->value()); }// 設置播放模式槽函數 void AudioPlay::on_PushButton_PlayMode_clicked() { // qDebug() << __FUNCTION__;switch(playerMode++){case 0: ui->PushButton_PlayMode->setIcon(QIcon(":/image/danquxunhuan.png"));ui->PushButton_PlayMode->setIconSize(QSize(48,48));playerList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); // 單曲循環break;case 1: ui->PushButton_PlayMode->setIcon(QIcon(":/image/suijibofang.png"));ui->PushButton_PlayMode->setIconSize(QSize(48,48));playerList->setPlaybackMode(QMediaPlaylist::Random); // 隨機播放break;case 2: ui->PushButton_PlayMode->setIcon(QIcon(":/image/yinlebofangye-xunhuanbofang.png"));ui->PushButton_PlayMode->setIconSize(QSize(48,48));playerList->setPlaybackMode(QMediaPlaylist::Loop); // 循環播放break;}if(playerMode == 3) playerMode = 0; }// 刪除歌曲 void AudioPlay::on_PushButton_DeleteMusic_clicked() { // qDebug() << __FUNCTION__;if(playerList->mediaCount() == 0) return;configIniDelete = new QSettings("PlayList.ini",QSettings::IniFormat);int curPlayIndex = ui->tableWidget->currentRow();if( curPlayIndex >= 0){for (int i = curPlayIndex; ; i++){if(configIniDelete->value("/song/"+QString::number(i+1),100).toInt() != 100) //{configIniDelete->setValue("/song/"+QString::number(i),configIniDelete->value("/song/"+QString::number(i+1)).toString());}else{configIniDelete->remove("/song/"+QString::number(i));break;}}playerList->removeMedia(curPlayIndex);ui->tableWidget->removeRow(curPlayIndex);} }bool AudioPlay::eventFilter(QObject *obj, QEvent *e) { // qDebug() << __FUNCTION__;if (obj == ui->centralWidget){if(e->type() == QEvent::MouseButtonDblClick){on_pushButton_WindowMax_clicked();return true;}}return QObject::eventFilter(obj, e); }void AudioPlay::mousePressEvent(QMouseEvent *e)//鼠標按下事件 {qDebug() << __FUNCTION__;if (e->button() == Qt::LeftButton){mDrag = true;mDragPos = e->globalPos() - pos();e->accept();} }void AudioPlay::mouseMoveEvent(QMouseEvent *e)//鼠標移動事件 {qDebug() << __FUNCTION__;if (mDrag && (e->buttons() && Qt::LeftButton)){move(e->globalPos() - mDragPos);e->accept();} }void AudioPlay::mouseReleaseEvent(QMouseEvent *e)//鼠標釋放事件 {qDebug() << __FUNCTION__;mDrag = false; }void AudioPlay::on_pushButton_WindowMin_clicked() {showMinimized(); }void AudioPlay::on_pushButton_WindowMax_clicked() {if (mIsMax){setGeometry(mLocation); // ui->pushButton_WindowMax->setIcon(QIcon(":/image/max1.png")); // ui->pushButton_WindowMax->setToolTip(QStringLiteral("最大化"));}else{mLocation = geometry();setGeometry(qApp->desktop()->availableGeometry()); // ui->pushButton_WindowMax->setIcon(QIcon(":/image/max2.png")); // ui->pushButton_WindowMax->setToolTip(QStringLiteral("還原"));}mIsMax = !mIsMax;}void AudioPlay::on_pushButton_WindowExit_clicked() {qApp->exit(); }//接受拖拽的文件 void AudioPlay::dragEnterEvent(QDragEnterEvent * event) {qDebug()<<__FUNCTION__;event->acceptProposedAction(); //接受拖拽的文件 }// 獲取拖拽的文件名 void AudioPlay::dropEvent(QDropEvent * event) {qDebug()<<__FUNCTION__;QString fileInfo;QFileInfo Info;bool status = false;auto urls = event->mimeData()->urls();for(auto it = urls.begin();it != urls.end();++it) //獲取拖拽的文件名{fileInfo = it->toLocalFile();Info = QFileInfo(it->toLocalFile());qDebug()<<it->toLocalFile();}QString fileName = Info.completeBaseName(); // 文件名不帶后綴QString fileSuffix = Info.suffix(); // 文件后綴// list << "*.mp3" << "*.wav" << "*.wma" << "*.flac" << "*.wmv" << "*.mp4" << "*.mov" << "*.avi" ;if(fileSuffix != "mp3" &&fileSuffix != "wav" &&fileSuffix != "wma" &&fileSuffix != "flac" &&fileSuffix != "wmv" &&fileSuffix != "mp4" &&fileSuffix != "mov" &&fileSuffix != "avi") return;if(playerList->mediaCount() > 0){for (int i = 0;i < playerList->mediaCount() ; i++){QString songName = ui->tableWidget->item(i,0)->text(); // 取出字符串if(songName == fileName + "." + fileSuffix) // 判斷是否是重復添加歌曲{status = true;break;}}}if(status == false){playerList->addMedia(QUrl(fileInfo)); // 把掃描得到的歌曲添加到播放列表上。帶路徑的int rownum = ui->tableWidget->rowCount();ui->tableWidget->insertRow(rownum);ui->tableWidget->setItem(rownum, 0, new QTableWidgetItem(fileName + "." + fileSuffix));configIniWrite->setValue("/song/"+QString::number(rownum), fileInfo); // 保存歌曲列表player->setPlaylist(playerList); // 把播放列表添加到播放器playMusic(rownum);}}播放器已經打包好,直接雙擊就可以運行(這里就不介紹QT打包項目過程)
剛運行是沒有歌曲和視頻的,需要手動添加(點擊幫助會跳到本人博客界面)
也可以用鼠標把歌曲或視頻拖到窗口
程序源碼:https://github.com/Lifashi/QT-AudioPlayhttps://github.com/Lifashi/QT-AudioPlay有不懂的地方可以私聊
總結
- 上一篇: 前端学习(1892)vue之电商管理系统
- 下一篇: 前端学习(1938)vue之电商管理系统