Python中如何使用PyQt5播放器制作个性化歌单

GitHub 上的截图

特性

  1. Window/Linux/macOS 上均可使用
  2. 支持搜索和播放 QQ 音乐,网易云,虾米音乐上的 免费 音乐资源;支持登录网易云和虾米音乐账号
  3. 最新功能: 一个歌单里既可以有周杰伦的歌曲,也能有 Taylor Swift 的歌曲,而且双击就能听!
  4. 扩展能力强
    • 终端重度患者可以在 shell 中使用
    • Emacs 玩家可以通过 elisp 控制
    • 年纪大了的话,也可以使用直接使用 GUI

安装使用

这里以 Ubuntu 为例

# Ubuntu 用户可以依次执行以下命令进行安装
sudo apt-get install python3-pyqt5  # 安装 Python PyQt5 依赖包
sudo apt-get install libmpv1        # 安装 libmpv1 系统依赖

pip3 install ‘feeluown>=2.3’ --user -i https://pypi.org/simple/

为 feeluown 生成图标( Linux 用户)

feeluown-genicon # 生成图标

视频与截图

Mac 顶部栏显示歌词 image 在 Emacs 中进行控制 image

更多请点击视频和截图


last but not least

在这里,你可能可以

  • 结识一帮有趣的朋友
  • 了解一个播放器程序是怎样从 0 到 1 完成的
  • 交流 Python 装饰器、描述器、元类等黑魔法在实际项目中的使用姿势
  • 体验知识技术分享、Code Review 等有趣、富有挑战的多人协作交流
  • ...

最后的最后,新年快乐 ~


Python中如何使用PyQt5播放器制作个性化歌单

15 回复

程咬金帮顶


要搞个带个性化歌单的PyQt5播放器,核心是结合QMediaPlayer、QMediaPlaylist和自定义的UI组件。下面这个示例展示了如何创建一个带播放列表管理的基础播放器。

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                             QHBoxLayout, QPushButton, QListWidget, QLabel, 
                             QFileDialog, QListWidgetItem, QSlider, QStyle)
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QMediaPlaylist
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QIcon

class MusicPlayer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.initPlayer()
        
    def initUI(self):
        self.setWindowTitle('个性化歌单播放器')
        self.setGeometry(300, 300, 500, 400)
        
        # 中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        
        # 当前播放标签
        self.current_song_label = QLabel('当前未播放')
        main_layout.addWidget(self.current_song_label)
        
        # 播放列表
        self.playlist_widget = QListWidget()
        main_layout.addWidget(self.playlist_widget)
        
        # 控制按钮
        control_layout = QHBoxLayout()
        
        self.play_btn = QPushButton()
        self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.play_btn.clicked.connect(self.toggle_play)
        
        self.prev_btn = QPushButton()
        self.prev_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.prev_btn.clicked.connect(self.play_previous)
        
        self.next_btn = QPushButton()
        self.next_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.next_btn.clicked.connect(self.play_next)
        
        control_layout.addWidget(self.prev_btn)
        control_layout.addWidget(self.play_btn)
        control_layout.addWidget(self.next_btn)
        
        # 音量控制
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(70)
        self.volume_slider.valueChanged.connect(self.set_volume)
        control_layout.addWidget(QLabel('音量:'))
        control_layout.addWidget(self.volume_slider)
        
        main_layout.addLayout(control_layout)
        
        # 歌单管理按钮
        manage_layout = QHBoxLayout()
        
        self.add_btn = QPushButton('添加歌曲')
        self.add_btn.clicked.connect(self.add_songs)
        
        self.remove_btn = QPushButton('移除选中')
        self.remove_btn.clicked.connect(self.remove_selected)
        
        self.clear_btn = QPushButton('清空歌单')
        self.clear_btn.clicked.connect(self.clear_playlist)
        
        manage_layout.addWidget(self.add_btn)
        manage_layout.addWidget(self.remove_btn)
        manage_layout.addWidget(self.clear_btn)
        
        main_layout.addLayout(manage_layout)
        
    def initPlayer(self):
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)
        
        # 连接信号
        self.player.stateChanged.connect(self.on_state_changed)
        self.playlist.currentIndexChanged.connect(self.on_song_changed)
        self.playlist_widget.itemDoubleClicked.connect(self.play_selected)
        
    def add_songs(self):
        files, _ = QFileDialog.getOpenFileNames(
            self, '选择音乐文件', '', 
            '音频文件 (*.mp3 *.wav *.ogg *.flac);;所有文件 (*.*)'
        )
        
        for file in files:
            url = QUrl.fromLocalFile(file)
            self.playlist.addMedia(QMediaContent(url))
            item = QListWidgetItem(file.split('/')[-1])
            self.playlist_widget.addItem(item)
            
    def remove_selected(self):
        current_row = self.playlist_widget.currentRow()
        if current_row >= 0:
            self.playlist.removeMedia(current_row)
            self.playlist_widget.takeItem(current_row)
            
    def clear_playlist(self):
        self.playlist.clear()
        self.playlist_widget.clear()
        
    def toggle_play(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            self.player.play()
            
    def play_previous(self):
        self.playlist.previous()
        
    def play_next(self):
        self.playlist.next()
        
    def play_selected(self, item):
        row = self.playlist_widget.row(item)
        self.playlist.setCurrentIndex(row)
        self.player.play()
        
    def set_volume(self, value):
        self.player.setVolume(value)
        
    def on_state_changed(self, state):
        if state == QMediaPlayer.PlayingState:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            
    def on_song_changed(self, index):
        if index >= 0 and index < self.playlist_widget.count():
            item = self.playlist_widget.item(index)
            self.current_song_label.setText(f'正在播放: {item.text()}')
            self.playlist_widget.setCurrentRow(index)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    player = MusicPlayer()
    player.show()
    sys.exit(app.exec_())

这个实现包含了:

  1. QMediaPlaylist 管理播放列表,支持添加、删除、清空操作
  2. QListWidget 显示歌单,双击可直接播放
  3. 基础播放控制:播放/暂停、上一首/下一首
  4. 音量控制:通过滑块调节
  5. 状态更新:实时显示当前播放的歌曲

要扩展个性化功能,可以考虑:

  • 添加歌单保存/加载功能(用json或数据库)
  • 实现歌曲拖拽排序
  • 添加歌曲标签编辑(歌手、专辑等)
  • 支持播放模式切换(顺序、随机、单曲循环)

总结:用QMediaPlaylist管理播放列表,结合QListWidget实现可视化操作。

挺漂亮,,顶一下

66666666

没找到 exe 啊,pong 友
Window (划掉)/Linux/macOS 上均可使用

windows 上也可以通过 pip 安装 ~
如果有兴趣,细节可以在 telegram 的群里提出或者私聊

安琪拉在此谢过…

喵喵喵,为啥我的 telegram 从来都登录不了???是不是姿势不正确

厉害,已 star。从 commit 看到楼主坚持了很多年这个项目,再次膜拜

Telegram 需要梯子,是不是这个原因?

中间也是断断续续的维护,工作之后进展就比较慢了。感兴趣的话,一起来折腾呀 ~

不是吧,我又梯子哇

小白想问。。所以之前的歌单是什么样子的-=。=

之前的歌单,要不只能包含网易云的歌曲,要么只能包含虾米的歌曲。这个歌单可以包含多个平台的歌曲 ~

回到顶部