Python点阵字玩转动态歌词

Python 点阵字玩转动态歌词

  • Python实现动态歌词
    • 歌词lrc文件
    • 代码
    • 读取时间标签
    • 按时间打印歌词
  • 歌词转点阵字
  • 歌曲播放
  • 最终成果
  • 代码下载
  • 后续问题

上一篇中,我们可以自定义输入汉字,然后用点阵字来展现,接下来我们挖掘下更有趣的玩法。想法来自于听歌时桌面动态歌词,我们的点阵字可以自定义输入识别,何不加载歌词文件随着歌曲播放动态显示呢?走起——

Python实现动态歌词

歌词lrc文件

这个以前玩mp3的应该不陌生,就是配在歌曲mp3文件边上的那个后缀lrc文件。lrc是英文lyric即歌词的缩写。Lrc文件可以用文本编辑器直接打开,其内容分为标识标签时间标签,如图
Python点阵字玩转动态歌词_第1张图片

标识标签指 [ti:歌曲名]、[ar:歌手名]、[al:专辑名]、 [offset:时间补偿值]这类介绍信息。

时间标签指[mm:ss.ff]加对应歌词,mm:ss.ff是分钟和精确到百分位的秒数,当歌曲播放到特定的时间点,根据时间标签读取对应的歌词文本,实现歌词同步、动态显示。

搞清lrc的格式,任务也就很清晰了,读取文件中的时间标签,解析出我们需要的时间和对应的歌词文本,定时按文本打印输出点阵字就可以了。

代码

import re
import time
import printPlay
import codecs
openLyric = codecs.open("无条件.lrc",encoding='utf-8')
lyricList = openLyric.readlines()
timeTable = []
lyricDict = {}
timeDict = {}

pattern = r'\d{2}:\d{2}.\d{2}'
for str in lyricList:
    strList = str.split(']')
    for i in range(len(strList)-1):
        if re.match(pattern,strList[i][1:]):
            t = (int(strList[i][1:][:2]) * 60 + int(strList[i][1:][3:5]))+ int(strList[i][1:][6:8])*0.01
            timeTable.append(t)
            lyricDict[t] = strList[-1][:-1]
#print(lyricDict)
#print(timeTable)

p = 0
for t in timeTable:
    time.sleep(t-temp)
    temp = t
    text = ''.join(lyricDict[t].split(' '))
    #printPlay.printPlay(text,'★',' ')
    printPlay.printPlay(text, '0', ' ')

读取时间标签

涉及到lrc文件的编码格式,直接读取会报错,引入codecs来读取文件。

读取文本我采用了readlines(),读取整个文件所有行,每行作为一个元素保存到一个列表list中。学python的新手朋友可以回顾下读取文件read()、readline()和这里的readlines()的区别,这里选用readlines() 是因为lrc本身不大,直接读到列表中也方便后续操作。

接下来都是Python入门的应用,拿到了读取出的列表,接下来要遍历列表,也就是检查每一项,挑选出符合时间标签格式的字符串,把字符串分离成时间数字和歌词文本。

按时间打印歌词

拿“[00:02.88]无条件“为例,在第2.88秒时将“无条件”打印输出,再到下一句的5.59秒,输出下一个文本,这里我才用了最简单的方式利用time模块的time.sleep(t) 来推迟执行命令。这样缺点是忽略了执行代码的运行时间,还要计算两句歌词间的时间差来进行赋值。不过好在影响不大而且这样做代码简单、新手友好,就先采用这方案好了。

歌词转点阵字

这里可以拿之前写的代码直接用,导入定义点阵字打印方法的py文件名 import printPlay,在新的代码文件中直接调用printPlay.printPlay()就好了。

相较之前的printPlay.py文件,我做了些改动,将运行printPlay.py时要执行的代码放入main中然后__name__先做个判断再执行。

name__是标识模块名字的一个系统变量:假如当前模块是主模块来直接执行,那么此模块名字就是__main,通过判断直接执行主函数内容;假如此模块是被import的,则此模块名字为文件名字,跳过if语句中的内容,再被import中的文件中,通过 文件名.函数 来执行被调用的函数。

def main():
    inpt = input("写你所想:")
    #lineSign = '■'
    lineSign = "0"

    #backgroundSign = '○'
    backgroundSign = "."

    printPlay(inpt,lineSign,backgroundSign)


if __name__ == '__main__':
    main()

歌曲播放

歌词搞定,接下来是歌曲,我们选用pygame的mp3播放功能。这个需要安装pygame, 可以通过pip install pygame来直接操作。

装好后在py文件中import pygame ,接下来就是三行代码来初始化、读取、播放了。

import pygame
pygame.mixer.init()
track = pygame.mixer.music.load('无条件.mp3')
pygame.mixer.music.play()

注意,要将mp3和lrc文件都放在和py文件同一个文件夹,如果改变路径,则需要在代码中lrc和mp3读取处添加对应路径。

最终成果

由于csdn不能上传视频,只能用图片了,可以在微信公众号文章中查看录屏视频
Python点阵字玩转动态歌词_第2张图片

代码下载

github下载链接:
https://github.com/pengfexue2/lyricPlay.git

后续问题

  1. 目前lrc文件还挺难找的,这个我再研究下网易云音乐的歌词文件
  2. lrc编码格式以及内容字符也有影响,因为我这只能提取汉字,这个也要再后续改进
  3. 点阵字占用空间太大,显示方面需要再想办法解决一下当然如果不采用点阵字打印
    直接输出歌词,就是一个简单的音乐播放配动态歌词的功能了。
  4. 目前代码中只是开始播放一直到结束,并没有添加对播放的控制,这个也可以增加。目前代码中只是开始播放一直到结束,并没有添加对播放的控制,这个也可以增加。
  5. 可以给播放器添加图形界面,以及播放按钮、调节音量等。

暂时想到这些,挖的坑有点多,慢慢更新。。欢迎关注我的微信公众号,共同成长~
Python点阵字玩转动态歌词_第3张图片

你可能感兴趣的:(python学习,python资源)