Pyqt5制作音乐播放器

在这里插入图片描述

背景故事

基于Pyqt5制作的一款本地离线音乐播放器,支持.mp3和.wav音频文件的播放。开发初衷是省去每个月听歌会员,把喜欢的歌曲录制或转码下载到本地,即可永久使用了。

现有功能

  1. 选择指定文件夹的歌曲;
  2. 点击歌曲进行播放,再次点击暂停;
  3. 播放的进度条;

依赖安装

pip install pydub PyQT5

源码参数

源文件两个,music.ui和music.py,将两个文件放在同一目录下运行music.py即可。

music.py

import os

from pydub import AudioSegment

from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QFileDialog, QTableView, QMainWindow
from PyQt5 import uic
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtCore import QUrl

class Music_Player(QMainWindow):
                                                                            
    def __init__(self):
        super().__init__()
        # 初始化根目录
        self.root_name = None
        # 初始化歌曲名称
        self.sing_name = ''
        # 初始化点击次数
        self.clicked_count = {}
        # 初始化播放器
        self.player = QMediaPlayer(self)
        self.player.positionChanged.connect(self.update_progress)

        # 动态加载UI文件
        self.ui = uic.loadUi('Music Player.ui')
        # 按钮绑定
        self.ui.pushButton.clicked.connect(self.select_dir)
        self.ui.tableView.clicked.connect(self.table_clicked)

        # 创建一个数据模型
        self.model = QStandardItemModel()
        # 设置表头
        self.model.setHorizontalHeaderLabels(["歌名", "歌手", "时长"])
        # 将数据模型设置给表格视图
        self.ui.tableView.setModel(self.model)
        # 设置表格视图的属性
        self.ui.tableView.setEditTriggers(QTableView.NoEditTriggers)  # 禁止编辑
        self.ui.tableView.setSelectionBehavior(QTableView.SelectRows)  # 选择整行

        #设置列宽
        self.ui.tableView.setColumnWidth(0, 190)
        self.ui.tableView.setColumnWidth(1, 190)
        self.ui.tableView.setColumnWidth(2, 190)
        self.ui.progressBar.setRange(0, 100)
        
    def select_dir(self):
        # 选择文件夹
        FileDirectory = QFileDialog.getExistingDirectory(None, "选择歌曲文件夹", "D:/")
        self.root_name = FileDirectory
        # 获取目录列表
        file_list = [i for i in os.listdir(FileDirectory) if i.endswith('mp3') or i.endswith('wav')]
        if len(file_list) == 0:
            pass
        else:
            result = []
            # 获取文件夹名称 ,歌手信息
            root_name = os.path.basename(FileDirectory)
            for file in file_list:
                obj_path = os.path.join(FileDirectory, file)
                duration = self.get_audio_duration(obj_path)
                result.append([file, root_name, duration])  # [:-4]
                self.clicked_count[file] = 0
            # 填充tabelView
            for row in range(len(result)):
                for column in range(3):
                    item =  QStandardItem(result[row][column])
                    #设置每个位置的文本值
                    self.model.setItem(row,column, item)

    def get_audio_duration(self, file_path):
        # 获取音频的时长
        audio = AudioSegment.from_file(file_path)
        duration = audio.duration_seconds
        minutes = int(duration / 60)
        seconds = int(duration % 60)
        return f"{minutes}:{seconds:02d}"

    def table_clicked(self, index):
        # 获取选中行的数据
        row = index.row()
        # 获取歌曲名称
        sing_name = self.model.item(row, 0).text()
        # 获取歌曲路径
        sing_path = os.path.join(self.root_name, sing_name)
        # 获取点击次数
        count = self.clicked_count[sing_name]
        if count % 2 == 0:  
            # 偶数次点击,执行播放操作
            media_content = QMediaContent(QUrl.fromLocalFile(sing_path))
            self.player.setMedia(media_content)
            self.player.play()
        else:
            # 奇数次点击,执行暂停操作
            self.player.pause()
        # 更新点击次数
        self.clicked_count[sing_name] += 1

    def update_progress(self, position):
        # 更新进度条
        duration = self.player.duration()
        if duration > 0:
            progress = position / duration * 100
            self.ui.progressBar.setValue(int(progress))

app = QApplication([])
Music = Music_Player()
Music.ui.show()
app.exec_()

music.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>mainWindow</class>
 <widget class="QMainWindow" name="mainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>791</width>
    <height>557</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="layoutDirection">
   <enum>Qt::LeftToRight</enum>
  </property>
  <property name="autoFillBackground">
   <bool>false</bool>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>50</y>
      <width>75</width>
      <height>24</height>
     </rect>
    </property>
    <property name="text">
     <string>选择曲库</string>
    </property>
   </widget>
   <widget class="QTableView" name="tableView">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>110</y>
      <width>650</width>
      <height>301</height>
     </rect>
    </property>
    <property name="frameShadow">
     <enum>QFrame::Plain</enum>
    </property>
   </widget>
   <widget class="QProgressBar" name="progressBar">
    <property name="geometry">
     <rect>
      <x>140</x>
      <y>460</y>
      <width>511</width>
      <height>16</height>
     </rect>
    </property>
    <property name="value">
     <number>0</number>
    </property>
    <property name="textVisible">
     <bool>true</bool>
    </property>
   </widget>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>791</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值