提问:你平常都是如何听歌和下载歌曲的?官网?软件?

简介:作为计算机的爱好者,对计算的使用已经是非常熟悉了解的了,当然对编程语言也是有些许了解。听周围人说,无法听取某些歌曲或下载某些歌曲,身为脚本小子的我,分析了对应网页,编写了一个音乐播放器,并且歌曲对应的歌词也会随音乐的播放进行滚动。

一、导入需要的库

        工欲善其事必先利其器,在开始编写时,先分析好大概的结构和所需的功能,导入对应的第三方库。

import tkinter as tk      GUI 界面搭建
import time               计时
import requests            网页请求库
import urllib.parse as parse      格式化字符编码
import json              json数据分析
import os                系统库
from pygame import mixer    #音乐播放
from mutagen.mp3 import MP3  # 用来的到一个.mp3文件的时长

        二、构建GUI界面

        这里使用的是tkinter来创建界面,这个库,搭建界面简单便捷,小巧,并且容易打包

 tk.Tk()    创建一个主窗口


title        标题 


geometry("长x宽")                设置窗口的长宽

geometry("长x宽+x轴位置+y轴位置")          设置窗口的长宽以及在窗口的显示位置


font             字体     字号


grid            布局     行   列


StringVar() 字符串变量类型

command                调用函数


mainloop()                显示窗口

root = tk.Tk()
root.title("######音乐播放器")
root.geometry("800x400")

input_lable = tk.Label(root,text="请输入歌名或作者:",font=('楷体',12))
input_lable.grid(row=1,column=0)

input_en = tk.StringVar()
input_entry = tk.Entry(root,textvariable=input_en,font=("楷体",12))
input_entry.grid(row=1,column=1)


index_input = tk.Button(root,text="搜索",command=select_1)
index_input.grid(row=1,column=2)


#歌曲列表
list_box = tk.Listbox(root,font=('楷体',12),width=43,height=21)
list_box.grid(row=2,column=0,columnspan=3,rowspan=5)


#歌词
text = tk.Text(root,width=63,height=20)
text.grid(row=2,column=3,rowspan=3,columnspan=5)

b_buttom = tk.Button(root,text="播放",command=select_2)
b_buttom.grid(row=5,column=3)


tk.mainloop()

二、歌曲id和歌曲名下载

with open(f'{zuoze}.mp3', 'wb') as f:

with open('文件名和后缀','读取或写入方式')  as 小名


打开的文件如果不存在,便会新建一个        WB   二进制写入

def M_musci(music_name):
    file = open("m1.txt", 'w').close()
    print(music_name)    #音乐名称
    keyword = parse.urlencode({'keyword': music_name})      #构建参数
    keyword = keyword[keyword.find('=') + 1:]      #去除建
    #请求头
    headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}
    #拼接网址
    url = f"https://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={keyword}&type=1&offset=0&total=true&limit=20"
    #文本数据
    response = requests.get(url, headers=headers).json()
    json_list = response["result"]["songs"]
    for i in json_list:
        print(i)
        ID = i['id']
        name = i['name']
        str_zuozhe = i['artists']
        for j in str_zuozhe:
            str_zuozhe=j['name']

        with open("m1.txt",'a',encoding='utf-8') as f:
            f.write(str_zuozhe+'\t'+name+'\t'+str(ID)+'\n')

三、文件处理函数

read    读取文件

split()      去除尾部不需要的字符

def Information_from_file():     #文件处理函数
    with open('m1.txt','r',encoding='utf-8') as f:    #读取保存的歌曲文件
        str_1=f.read()    #读取
        # print(str_1)
    list_1=str_1.split('\n')[:-1]     #去除换行符    取0到末尾
    print(list_1)
    song_names=[];song_name=[];song_id=[]     #三个列表变量     歌曲名    歌曲哈希值   歌曲ID
    for str_2 in list_1:    #遍历读取的字符
        str_2=str_2.split('\t')    #去除格式符
        print(str_2)

        song_names.append(str_2[0])    #作者
        song_name.append(str_2[1])     #名称
        song_id.append(str_2[2])       #歌曲ID

    return song_names,song_name,song_id     #返回这三个列表

四、歌曲下载函数

append        数据添加进列表

writer          文件写入

time.time()     获取当前时间

def Downlad(zuoze,music_id):     #音乐的下载传递两个参数     音乐哈希值    音乐ID
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}
    # 发送请求

    url = f'https://music.163.com/api/song/lyric?id={music_id}&lv=1&kv=1&tv=-1'
    response = requests.get(url, headers=headers).json()
    # print(response['lrc'])
    list = response['lrc']['lyric']
    list_1 = list.split('\n')[:-1]
    print(list_1)
    song_list = []
    time_list = []
    for str_1 in list_1:
        # 歌曲时间
        str_2 = str_1[:str_1.find(']') + 1]
        time_list.append(str_2)

        str_1 = str_1[str_1.find(']') + 1:]
        song_list.append(str_1)
    print(song_list)
    print(time_list)

    time_list = Get_Time(time_list)  # 时间列表
    new_url = f"http://music.163.com/song/media/outer/url?id={music_id}.mp3"
    response = requests.get(new_url, headers=headers).content
    with open(f'{zuoze}.mp3', 'wb') as f:
        f.write(response)
    start_time = time.time()
    audio = MP3(f'{zuoze}.mp3')
    untime = time.time()
    time_music = audio.info.length
    mixer.init()
    mixer.music.load(f'{zuoze}.mp3')
    mixer.music.play()
    mixer.stop()
    return True, time_list, song_list, time_music

五、歌曲搜索函数

delete(从0位开始,结尾结束)

get()      获取输入的值

insert(开始位置,插入的字符串)

def select_1():   #选择
    list_box.delete(0,tk.END)
    M_musci(input_en.get())    #输入的值

    list_1=Information_from_file()[1]    #歌曲名
    for i in range(len(list_1)):   #遍历歌曲名
        list_box.insert(tk.END,str(list_1[i]))    #显示歌曲名

六、播放函数

update      数据更新

def select_2():
    dict_id={}
    dict_name={}    #定义两个变量
    text.delete(0.0,tk.END)
    list_1=Information_from_file()[0] # 作者
    list_2=Information_from_file()[1]  # 名称
    list_3=Information_from_file()[2]  # id
    for i in range(len(list_2)):  #遍历歌曲名
        print(list_2[i])
        dict_id[list_2[i]]=list_2[i]    #将哈希  传递给对应的音乐名   name:哈希值
        dict_name[list_2[i]]=list_3[i]  #将ID  传递给对应的name    name:ID
    print(dict_name,dict_id)
    name_1 = list_box.get(tk.ACTIVE)
    zuoze = dict_id[name_1]  # 获取对应的音乐ID
    print(zuoze)
    id1 = dict_name[name_1]  # 获取对应的音乐哈希值
    bool_1=Downlad(zuoze,id1)
    # 显示一个进度条
    for i in range(1, 101):
        tk.Label(root, text='{}%|{}'.format(i, int(i / 4 % 26) * '■')).grid(row=5, columnspan=2, column=6, sticky=tk.W)
        root.update()  # 更新
    time_list = bool_1[1]  # 时间列表
    song_list = bool_1[2]  # 歌曲列表
    music_time = bool_1[3]  # 音乐时间
    i = 0
    T = 0

    while True:
        # end_time = time.time()
        try:
            # time.sleep(((time_list[T]) - time_list[T])+1)
            text.insert('{}.0'.format(i + 1), (song_list[i] + '\n').center(56, ' '))  # 将第一行插入歌曲列表的第i个   居中显示
            text.update()
            # text.send(tk.END)
            text.see(tk.END)
            i += 1


            if T == 0:  # 真
                time.sleep(time_list[T])  # 暂停几秒
            elif T == len(time_list)-1:  #
                time.sleep(4)
            else:
                time.sleep(time_list[T+1] - time_list[T])

            T += 1

            root.update()

        except:
            break

七、音乐播放歌词时间函数

def Get_Time(time_list):
    for i in range(len(time_list)):   #遍历时间列表
        minute = time_list[i][1:3]    #分
        second = time_list[i][4:6]    #秒
        h_second = time_list[i][7:9]   #毫秒
        time_list[i] = int(minute) * 60 + int(second) + float('0.' + h_second)   #时间列表
    return time_list

八、全部源码

# -*- coding:utf-8 -*-
"""
File name : main.PY
Program IDE : PyCharm
Create file time: 2022/10/19 11:46
File Create By Author : 小梦
"""

import tkinter as tk

import tkinter as tk
import time
import requests
import urllib.parse as parse
import json
import os
from pygame import mixer    #音乐播放
from mutagen.mp3 import MP3  # 用来的到一个.mp3文件的时长
def M_musci(music_name):
    file = open("m1.txt", 'w').close()
    keyword = parse.urlencode({'keyword': music_name})      #构建参数
    keyword = keyword[keyword.find('=') + 1:]      #去除建

    headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}

    url = f"https://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={keyword}&type=1&offset=0&total=true&limit=20"

    response = requests.get(url, headers=headers).json()
    json_list = response["result"]["songs"]
    for i in json_list:
        ID = i['id']
        name = i['name']
        str_zuozhe = i['artists']
        for j in str_zuozhe:
            str_zuozhe=j['name']
        with open("m1.txt",'a',encoding='utf-8') as f:
            f.write(str_zuozhe+'\t'+name+'\t'+str(ID)+'\n')


num=0
id_1=True

def Get_Time(time_list):
    for i in range(len(time_list)):   #遍历时间列表
        minute = time_list[i][1:3]    #分
        second = time_list[i][4:6]    #秒
        h_second = time_list[i][7:9]   #毫秒
        time_list[i] = int(minute) * 60 + int(second) + float('0.' + h_second)   #时间列表
    return time_list


def Information_from_file():     #文件处理函数
    with open('m1.txt','r',encoding='utf-8') as f:    #读取保存的歌曲文件
        str_1=f.read()    #读取

    list_1=str_1.split('\n')[:-1]     #去除换行符    取0到末尾
    song_names=[];song_name=[];song_id=[]     #三个列表变量     歌曲名    歌曲哈希值   歌曲ID
    for str_2 in list_1:    #遍历读取的字符
        str_2=str_2.split('\t')    #去除格式符

        song_names.append(str_2[0])    #作者
        song_name.append(str_2[1])     #名称
        song_id.append(str_2[2])       #歌曲ID

    return song_names,song_name,song_id     #返回这三个列表


def Downlad(zuoze,music_id):     #音乐的下载传递两个参数     音乐哈希值    音乐ID
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'}

    url = f'https://music.163.com/api/song/lyric?id={music_id}&lv=1&kv=1&tv=-1'
    response = requests.get(url, headers=headers).json()

    list = response['lrc']['lyric']
    list_1 = list.split('\n')[:-1]
    print(list_1)
    song_list = []
    time_list = []
    for str_1 in list_1:

        str_2 = str_1[:str_1.find(']') + 1]
        time_list.append(str_2)

        str_1 = str_1[str_1.find(']') + 1:]
        song_list.append(str_1)

    time_list = Get_Time(time_list)  # 时间列表
    new_url = f"http://music.163.com/song/media/outer/url?id={music_id}.mp3"
    response = requests.get(new_url, headers=headers).content
    with open(f'{zuoze}.mp3', 'wb') as f:
        f.write(response)
    start_time = time.time()
    audio = MP3(f'{zuoze}.mp3')
    untime = time.time()
    time_music = audio.info.length
    mixer.init()
    mixer.music.load(f'{zuoze}.mp3')
    mixer.music.play()
    mixer.stop()
    return True, time_list, song_list, time_music

def select_1():   #选择
    list_box.delete(0,tk.END)
    M_musci(input_en.get())    #输入的值

    list_1=Information_from_file()[1]    #歌曲名
    for i in range(len(list_1)):   #遍历歌曲名
        list_box.insert(tk.END,str(list_1[i]))    #显示歌曲名

def select_2():
    dict_id={}
    dict_name={}    #定义两个变量
    text.delete(0.0,tk.END)
    list_1=Information_from_file()[0] # 作者
    list_2=Information_from_file()[1]  # 名称
    list_3=Information_from_file()[2]  # id
    for i in range(len(list_2)):  #遍历歌曲名
        print(list_2[i])
        dict_id[list_2[i]]=list_2[i]    #将哈希  传递给对应的音乐名   name:哈希值
        dict_name[list_2[i]]=list_3[i]  #将ID  传递给对应的name    name:ID

    name_1 = list_box.get(tk.ACTIVE)
    zuoze = dict_id[name_1]  # 获取对应的音乐ID

    id1 = dict_name[name_1]  # 获取对应的音乐哈希值
    bool_1=Downlad(zuoze,id1)

    for i in range(1, 101):
        tk.Label(root, text='{}%|{}'.format(i, int(i / 4 % 26) * '■')).grid(row=5, columnspan=2, column=6, sticky=tk.W)
        root.update()  # 更新
    time_list = bool_1[1]  # 时间列表
    song_list = bool_1[2]  # 歌曲列表
    music_time = bool_1[3]  # 音乐时间
    i = 0
    T = 0

    while True:
        try:
            text.insert('{}.0'.format(i + 1), (song_list[i] + '\n').center(56, ' '))  # 将第一行插入歌曲列表的第i个   居中显示
            text.update()
            text.see(tk.END)
            i += 1
            if T == 0:  # 真
                time.sleep(time_list[T])  # 暂停几秒
            elif T == len(time_list)-1:  #
                time.sleep(4)
            else:
                time.sleep(time_list[T+1] - time_list[T])
            T += 1
            root.update()
        except:
            break

root = tk.Tk()
root.title("#####音乐播放器")
root.geometry("800x400")

input_lable = tk.Label(root,text="请输入歌名或作者:",font=('楷体',12))
input_lable.grid(row=1,column=0)

input_en = tk.StringVar()
input_entry = tk.Entry(root,textvariable=input_en,font=("楷体",12))
input_entry.grid(row=1,column=1)

index_input = tk.Button(root,text="搜索",command=select_1)
index_input.grid(row=1,column=2)

list_box = tk.Listbox(root,font=('楷体',12),width=43,height=21)
list_box.grid(row=2,column=0,columnspan=3,rowspan=5)

text = tk.Text(root,width=63,height=20)
text.grid(row=2,column=3,rowspan=3,columnspan=5)

b_buttom = tk.Button(root,text="播放",command=select_2)
b_buttom.grid(row=5,column=3)

tk.mainloop()

效果图

 

android 滚动歌词 滚动歌词编辑器_音乐播放

缺点:

        1、部分代码过于冗余,不够规范,运行有些卡顿

        1、点击播放时,会先将歌曲下载到本地,然后播放,待优化

        3、只能单首播放,且只有一次

        4、不能暂停