python实现在线音乐播放器(懒皮鼠音乐)

python实现在线音乐播放器(懒皮鼠音乐)

利用qt设计requests库实现在线音乐播放



效果如图


前言

本文主要提供使用python各种库的注意事项,内容仅供参考。


提示:以下是本篇文章正文内容,下面案例可供参考

一、qt设计师设计界面

在这里插入图片描述

将设计的ui生成py文件
可以参照:https://blog.csdn.net/zq1391345114/article/details/120104695

二、使用步骤

1.引入库

代码如下(示例):

from PySide2.QtWidgets import QApplication,QWidget
from PySide2.QtCore import QTimer#定时器
from PySide2.QtGui import QColor,QIcon
import  os
import re
import requests
import json
import urllib
from ui_ma import Ui_Form
from PySide2.QtWidgets import QMessageBox

2.读入数据

代码如下(示例):

  def __init__(self):
        #if not os.path.exists('data'):#判断文件夹是否存在
        os.makedirs('data\music',exist_ok=True)
        super().__init__()
        # 使用ui文件导入定义界面类
        self.ui = Ui_Form()
        # 初始化界面
        self.ui.setupUi(self)

该处省略绑定使用界


3.控件信号函数绑定相应槽函数

代码如下(示例):

self.ui.pushButton.clicked.connect(self.sousuo)#sousuo不可以带括号否则调试调用
self.ui.pushButton_2.clicked.connect(self.my_love)
self.ui.pushButton_3.clicked.connect(self.xiazai)
self.ui.pushButton_4.clicked.connect(lambda :self.xia(0))
self.ui.pushButton_5.clicked.connect(lambda :self.shang(0))
self.ui.pushButton_6.clicked.connect(self.no_love)
self.ui.pushButton_7.clicked.connect(lambda: self.shang(1))
self.ui.pushButton_8.clicked.connect(lambda: self.xia(1))
self.ui.pushButton_9.clicked.connect(self.exit)
self.ui.lineEdit.returnPressed.connect(self.sousuo)
"""************************************************"""
self.ui.listWidget_2.currentItemChanged.connect(self.change)#列表选中行修改信号
self.ui.listWidget.currentItemChanged.connect(self.change)

self.ui.listWidget.itemClicked.connect(lambda: self.bofang(0))  # 单击播放
#self.ui.listWidget.itemDoubleClicked.connect(self.my_love)  # 双击喜欢
#self.ui.listWidget_2.setCurrentRow(0)
#self.ui.listWidget_2.itemDoubleClicked.connect(self.no_love)#双击取消收藏
self.ui.listWidget_2.itemPressed.connect(lambda: self.bofang(1))  # 单击播放

提示:该处使用了lambda表达式表示匿名函数传参数


4.搜索获取音乐链接并播放

在各个音乐网站获取歌曲播放链接及时长,采用定时的方式播放下一曲音乐,这里是采用qt中的QwebEngineView实现在线播放

代码如下(示例):

     def bofang(self,m):
        if m==0:
            self.ui.web.setUrl("")#暂停第二界面播放
            i = self.ui.listWidget.currentRow()  # 获取选中序号
            m, s = self.music[i][2].strip().split(":")
            Time = int(m) * 60 + int(s)  # 获取歌曲时长
            rid = self.music[i][1]
            url = self.huoqu(rid)
            self.ui.webview.setUrl(url)
            self.timer = QTimer()
            #timer.stop()
            self.timer.timeout.connect(lambda:self.xia(0))#定时器绑定函数
            #timer.setSingleShot(True)#设置单次定时
            #QTimer.singleShot((Time+1)*1000, self.xia)#定时器
            self.timer.start((Time+2)*1000)#启动或重新启动定时器
        else:
            self.ui.webview.setUrl("")#暂停第一界面播放
            i = self.ui.listWidget_2.currentRow()  # 获取选中序号
            m, s = self.mylove[i][2].strip().split(":")
            Time = int(m) * 60 + int(s)  # 获取歌曲时长
            rid = self.mylove[i][1]
            url = self.huoqu(rid)
            self.ui.web.setUrl(url)
            self.timer = QTimer()
            self.timer.timeout.connect(lambda:self.xia(1))  # 定时器绑定函数
            self.timer.start((Time + 2) * 1000)  # 启动或重新启动定时器

这里可以看到
这里注意我注释了很多代码,他们都是不能正常之执行的。

我的本意是设置定时,歌曲播放完成后自动播放下一曲。那么有以下方法:

  1. sleep睡眠机制,很显然是行不通的,程序睡眠,歌曲也就不能播放。
  2. 多线程机制sleep单个线程,pyqt是不允许多线程机制的,我百度了下早期的python会直接报错,但是我这里没有报错,即使不用sleep睡眠,程序也会直接卡死。但是创建的子线程能够正常输出结果。
  3. threading定时器,这个定时器的原理也是创建一个子线程,所以它仍然不可用。
  4. QTimer定时器,它是pyqt中的定时器,可用。在我的代码中有注释掉一个QTimer,是因为他是一个成员变量,当点下一曲后上一个定时器还存在,所以后面就会出现歌曲没有播放完就下一曲的情况,解决方法是采用类变量。所有定时器共用一个内存。

其次播放过程中实现动态突出正在播放的歌曲那么就要采用currentItemChanged信号

   def change(self,item2,item1):
        item2.setBackgroundColor(QColor("red"))#设置选中行背景颜色
        if item1:
            item1.setBackgroundColor(QColor(0,0,0,0))  # 设置选中行背景颜色

这里设置了判断上一个item是否被选中。


## 5.下载

代码如下(示例):

   def xiazai(self):
        i = self.ui.listWidget.currentRow() # 获取选中序号
        rid =self.music[i][1]
        downloadurl=self.huoqu(rid)  # 根据rid获取url
        try:
            urllib.request.urlretrieve(url=downloadurl, filename='data/music/{}.mp3'.format(self.music[i][0]))
            QMessageBox.information(self,"消息", "下载成功.")
        except:
            QMessageBox.information(self,"消息", "下载错误,产生异常.")

提示:这里下载路径不存在就会下载失败,所以我们在开始就要判断下载路径是否存在,不存在就要利用代码os.makedirs('data\music',exist_ok=True)新建。


完整代码

提示:源码仅供参考。

from PySide2.QtWidgets import QApplication,QWidget
from PySide2.QtCore import QTimer#定时器
from PySide2.QtGui import QColor,QIcon
import  os
import re
import requests
import json
import urllib
from ui_ma import Ui_Form
from PySide2.QtWidgets import QMessageBox

class MainWindow(QWidget):
    music={}
    mylove={}
    def __init__(self):
        #if not os.path.exists('data'):#判断文件夹是否存在
        os.makedirs('data\music',exist_ok=True)
        super().__init__()
        # 使用ui文件导入定义界面类
        self.ui = Ui_Form()
        # 初始化界面
        self.ui.setupUi(self)
        self.shuaxin()
        # 使用界面定义的控件,也是从ui里面访问
        self.ui.pushButton.clicked.connect(self.sousuo)#sousuo不可以带括号否则调试调用
        self.ui.pushButton_2.clicked.connect(self.my_love)
        self.ui.pushButton_3.clicked.connect(self.xiazai)
        self.ui.pushButton_4.clicked.connect(lambda :self.xia(0))
        self.ui.pushButton_5.clicked.connect(lambda :self.shang(0))
        self.ui.pushButton_6.clicked.connect(self.no_love)
        self.ui.pushButton_7.clicked.connect(lambda: self.shang(1))
        self.ui.pushButton_8.clicked.connect(lambda: self.xia(1))
        self.ui.pushButton_9.clicked.connect(self.exit)
        self.ui.lineEdit.returnPressed.connect(self.sousuo)
        """************************************************"""
        self.ui.listWidget_2.currentItemChanged.connect(self.change)#列表选中行修改信号
        self.ui.listWidget.currentItemChanged.connect(self.change)

        self.ui.listWidget.itemClicked.connect(lambda: self.bofang(0))  # 单击播放
        #self.ui.listWidget.itemDoubleClicked.connect(self.my_love)  # 双击喜欢
        #self.ui.listWidget_2.setCurrentRow(0)
        #self.ui.listWidget_2.itemDoubleClicked.connect(self.no_love)#双击取消收藏
        self.ui.listWidget_2.itemPressed.connect(lambda: self.bofang(1))  # 单击播放
    def change(self,item2,item1):
        item2.setBackgroundColor(QColor("red"))#设置选中行背景颜色
        if item1:
            item1.setBackgroundColor(QColor(0,0,0,0))  # 设置选中行背景颜色
    def exit(self):
        self.ui.webview.setUrl("")
        self.ui.web.setUrl("")
        self.timer.stop()
    def no_love(self):
        i=self.ui.listWidget_2.currentRow()
        for j in range(len(self.mylove)-i-1):
            self.mylove[i]=self.mylove[i+1]
            i+=1
        del self.mylove[i]
        s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt","w")
        for j in range(len(self.mylove)):
            s.write(str(self.mylove[j]))
        s.close()
        self.shuaxin()
    def my_love(self):
        i = self.ui.listWidget.currentRow()  # 获取选中序号
        j=len(self.mylove)
        self.mylove[j]=self.music[i]
        s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt",'a')
        s.write(str(self.music[i]))
        s.close()
        self.ui.listWidget_2.addItem('【{}】'.format(j+1) + self.mylove[j][0])
    def shuaxin(self):
        self.ui.listWidget_2.clear()
        if os.path.exists("data/my_love(保存收藏音乐信息,请勿随意修改).txt"):
            s=open("data/my_love(保存收藏音乐信息,请勿随意修改).txt",'r')
            content=s.read()
            s.close()
            p = re.compile(r'\[.*?\]')
            i=0
            for one in p.findall(content):
                self.mylove[i]=eval(one)#将字符串转换成列表
                self.ui.listWidget_2.addItem('【{}】'.format(i + 1)+self.mylove[i][0])
                i+=1
    def sousuo(self):  # 获取下载rid
        musicname = self.ui.lineEdit.text()
        encodename = urllib.parse.quote(musicname)  # 对字符串进行编码
        url = 'https://www.kuwo.cn/api/www/search/searchMusicBykeyWord'
        headers = {
            "Cookie": "Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1611813721; _ga=GA1.2.1711987833.1611813721; _gid=GA1.2.1936491096.1611813721; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1611813751; _gat=1; kw_token=AMJKSZZ014",
            "csrf": "AMJKSZZ014", "Host": "www.kuwo.cn",
            "Referer": "http://www.kuwo.cn/search/list?key={}".format(encodename),
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.53", }
        data = {"key": "{}".format(musicname), 'pn': 1, "rn": 30, "httpsStatus": 1,
                "reqId": " f1b198b0-612e-11eb-b682-25ec8c838219"}  # 加入后会自动编码

        res = requests.request('get', url, headers=headers, params=data, timeout=1)
        dict = json.loads(res.text)
        if dict['code'] != 200:
            misicinfo = [{'name': '获取失败,请重试!', 'artist': ''}]
        else:
            misicinfo = dict['data']['list']
        self.ui.listWidget.clear()
        for i in range(len(misicinfo)):
            name = misicinfo[i]['name'] + '-' + misicinfo[i]['artist']
            self.music[i] = [name,misicinfo[i]['rid'],misicinfo[i]['songTimeMinutes']]#组建歌曲信息:名字,rid,时长
            self.ui.listWidget.addItem( '【{}】'.format(i + 1) + name)
        #self.ui.listWidget.setCurrentRow(0)#默认选中第一行
        #self.ui.listWidget.item(1).setBackgroundColor(QColor('red'))#设置颜色
    def huoqu(self,rid):  # 获取url
        url = 'http://www.kuwo.cn/url?'
        data1 = {"format": "mp3",
                 "rid": "{}".format(rid),
                 "response": "url",
                 "type": "convert_url3",
                 "br": "128kmp3",
                 "from": "web",
                 "t": 1611821852163,
                 "httpsStatus": 1}
        header1 = {
            "User-Agent": "ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.53"}
        res1 = requests.get(url, headers=header1, params=data1, timeout=1)
        return json.loads(res1.text)['url']
    def xiazai(self):
        i = self.ui.listWidget.currentRow() # 获取选中序号
        rid =self.music[i][1]
        downloadurl=self.huoqu(rid)  # 根据rid获取url
        try:
            urllib.request.urlretrieve(url=downloadurl, filename='data/music/{}.mp3'.format(self.music[i][0]))
            QMessageBox.information(self,"消息", "下载成功.")
        except:
            QMessageBox.information(self,"消息", "下载错误,产生异常.")
    def bofang(self,m):
        if m==0:
            self.ui.web.setUrl("")#暂停第二界面播放
            i = self.ui.listWidget.currentRow()  # 获取选中序号
            m, s = self.music[i][2].strip().split(":")
            Time = int(m) * 60 + int(s)  # 获取歌曲时长
            rid = self.music[i][1]
            url = self.huoqu(rid)
            self.ui.webview.setUrl(url)
            self.timer = QTimer()
            #timer.stop()
            self.timer.timeout.connect(lambda:self.xia(0))#定时器绑定函数
            #timer.setSingleShot(True)#设置单次定时
            #QTimer.singleShot((Time+1)*1000, self.xia)#定时器
            self.timer.start((Time+2)*1000)#启动或重新启动定时器
        else:
            self.ui.webview.setUrl("")#暂停第一界面播放
            i = self.ui.listWidget_2.currentRow()  # 获取选中序号
            m, s = self.mylove[i][2].strip().split(":")
            Time = int(m) * 60 + int(s)  # 获取歌曲时长
            rid = self.mylove[i][1]
            url = self.huoqu(rid)
            self.ui.web.setUrl(url)
            self.timer = QTimer()
            self.timer.timeout.connect(lambda:self.xia(1))  # 定时器绑定函数
            self.timer.start((Time + 2) * 1000)  # 启动或重新启动定时器
    def xia(self,m):
        if m==0:
            i = self.ui.listWidget.currentRow()+1  # 获取选中序号
            if i>=self.ui.listWidget.count():#判断是否是最后一曲
                i=0
            self.ui.listWidget.setCurrentRow(i)
        else:
            i=self.ui.listWidget_2.currentRow()+1
            if i>=self.ui.listWidget_2.count():#判断是否是最后一曲
                i=0
            self.ui.listWidget_2.setCurrentRow(i)
        self.bofang(m)
    def shang(self,m):
        if m==0:
            i = self.ui.listWidget.currentRow()-1  # 获取选中序号
            if i<0:#判断是否是第一曲
                i=self.ui.listWidget.count()-1
            self.ui.listWidget.setCurrentRow(i)#修改选中项
        else:
            i = self.ui.listWidget_2.currentRow() - 1  # 获取选中序号
            if i < 0:  # 判断是否是第一曲
                i = self.ui.listWidget_2.count() - 1
            self.ui.listWidget_2.setCurrentRow(i)  # 修改选中项
        self.bofang(m)
app = QApplication([])
mainw = MainWindow()
mainw.show()
app.exec_()

微信关注公众号懒皮鼠

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实现在线音乐播放器需要前端和后端的技术。前端技术可以使用HTML、CSS和JavaScript,后端技术可以使用Python。 下面是一个基于Python Flask框架实现在线音乐播放器的示例代码: ```python from flask import Flask, render_template, url_for, request import os app = Flask(__name__) @app.route("/") def index(): music_list = os.listdir("static/music") return render_template("index.html", music_list=music_list) @app.route("/play", methods=["POST"]) def play(): music_name = request.form["music_name"] return render_template("play.html", music_name=music_name) if __name__ == "__main__": app.run(debug=True) ``` 这是一个简单的后端代码,我们需要在`static/music`文件夹下放置音乐文件,然后通过前端页面来实现在线播放。下面是HTML代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>在线音乐播放器</title> </head> <body> <h1>在线音乐播放器</h1> <ul> {% for music in music_list %} <li> <form action="{{ url_for('play') }}" method="post"> <input type="hidden" name="music_name" value="{{ music }}" /> <button type="submit">{{ music }}</button> </form> </li> {% endfor %} </ul> </body> </html> ``` 这是主页的HTML代码,我们通过Python代码中的`music_list = os.listdir("static/music")`获取`static/music`文件夹下的所有音乐文件,然后通过循环展示在页面上。当用户点击某个音乐文件时,会提交一个POST请求到`/play`路由,Python代码中的`play()`函数会接收到这个请求,然后渲染一个新的页面。 下面是播放页面的HTML代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ music_name }}</title> </head> <body> <h1>{{ music_name }}</h1> <audio controls src="{{ url_for('static', filename='music/' + music_name) }}"></audio> </body> </html> ``` 这是播放页面的HTML代码,我们通过Python代码中的`music_name = request.form["music_name"]`获取用户选择的音乐文件名称,然后在页面上渲染出音乐名称和播放器。由于音乐文件在`static/music`文件夹下,因此我们使用`url_for('static', filename='music/' + music_name)`来获取音乐文件的URL。 这样,我们就完成了一个简单的在线音乐播放器实现。当用户访问`http://127.0.0.1:5000/`时,会展示出音乐列表,用户选择某个音乐文件后,会跳转到播放页面,自动播放该音乐文件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值