BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / python / #3516同步于 2014/9/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖

一个支持LRC的终端播放器

reverland
2014/9/29镜像同步10 回复
早上在控制台下用cvlc播放觉得不方便看歌词……于是折腾了…… 效果参见, http://ascii.io/a/12595 游泳去了 cpu占用只有%2,比cvlc效果还好,哈哈 站在巨人的肩膀上,仅仅60行代码。 #!/usr/bin/env python # -*- coding:utf-8 -*- from pygame import mixer import re import time import sys import random f_mp3 = sys.argv[1] f_lrc = sys.argv[2] def lrc2dict(lrc): lrc_dict = {} for line in lrc.split('\n'): m = re.search(r'\[([^\]]+)\]', line) if m: m.group(1) tag_flag = m.group(1).split(':')[0] if not tag_flag.isdigit(): continue time_lrc = int(tag_flag) * 60000 time_lrc += int(m.group(1).split(':')[1].split('.')[0]) * 1000 time_lrc += int(m.group(1).split('.')[1]) time_lrc = time_lrc / 100 lrc_dict[time_lrc] = line.replace(m.group(0), '') return lrc_dict def print_lrc(mixer, lrc_d, color): mixer.music.play() mixer.music.pause() time.sleep(0.001) mixer.music.play() while 1: t = mixer.music.get_pos() / 100 if t in lrc_d: sys.stdout.write(color + lrc_d[t] + '\033[0m' + '\r') sys.stdout.flush() # 向后清除 sys.stdout.write("\033[K") if t < 0: sys.exit(0) time.sleep(0.05) with open(f_lrc) as f: lrc = f.read() lrc_d = lrc2dict(lrc) mixer.init() mixer.music.load(f_mp3) colors = [ '\x1B[31m', # 红色 '\x1B[32m', # 绿色 '\x1B[33m', # 黄色 '\x1B[34m', # 蓝色 '\x1B[35m', # 紫色 '\x1B[36m', # 青色 '\x1B[37m' # 灰白 ] color = random.choice(colors) print_lrc(mixer, lrc_d, color)
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
Chon机器人#1 · 2014/9/29
妈蛋我想起来我大二时候用C写过...
reverland机器人#2 · 2014/9/30
容弱渣一拜~ 【 在 Chon 的大作中提到: 】 : 妈蛋我想起来我大二时候用C写过...
Chon机器人#3 · 2014/9/30
憋...用Windows API的黑历史 【 在 reverland 的大作中提到: 】 : 容弱渣一拜~
reverland机器人#4 · 2014/9/30
Win32 API?好腻害~ 【 在 Chon 的大作中提到: 】 : 憋...用Windows API的黑历史
qiukun机器人#5 · 2014/10/9
Orz
reverland机器人#6 · 2014/10/9
基于vlc重做了遍,pygame对mp3的支持太有限 https://asciinema.org/a/12843 现在终于像个播放器了…… 【 在 qiukun 的大作中提到: 】 : Orz
Valar机器人#7 · 2014/10/9
顶!对了,请问楼主,别的论坛里,代码都可以直接复制粘贴到文本编辑器里,咱们论坛里的代码为什么选择复制,然后粘贴到文本编辑器里就变成很长一行了。你的这个代码也是,请问,怎么才能完整复制?O(∩_∩)O~
qyz0123321机器人#8 · 2014/10/9
膜拜。。 【 在 Chon 的大作中提到: 】 妈蛋我想起来我大二时候用C写过...
reverland机器人#9 · 2014/10/10
我这里可以复制粘帖…… 试试手机版 http://m.byr.cn/article/Python/3516 基于vlc的 #!/usr/bin/env python # -*- coding:utf-8 -*- import vlc import re import time import sys import random f_mp3 = sys.argv[1] f_lrc = sys.argv[2] def lrc2dict(lrc): lrc_dict = {} remove = lambda x: x.strip('[|]') for line in lrc.split('\n'): time_stamps = re.findall(r'\[[^\]]+\]', line) if time_stamps: # 截取歌词 lyric = line for tplus in time_stamps: lyric = lyric.replace(tplus, '') # 解析时间 # tplus: [02:31.79] # t 02:31.79 for tplus in time_stamps: t = remove(tplus) tag_flag = t.split(':')[0] # 跳过: [ar: 逃跑计划] if not tag_flag.isdigit(): continue time_lrc = int(tag_flag) * 60000 time_lrc += int(t.split(':')[1].split('.')[0]) * 1000 # ms也许没有 try: time_lrc += int(t.split('.')[1]) except: pass # 截取到0.1s精度,降低cpu占用 time_lrc = time_lrc / 1000 * 1000 lrc_dict[time_lrc] = lyric return lrc_dict def print_lrc(player, lrc_d, color): player.play() player.pause() # 防止无法获取整个音频时长 # 音频时长必须加载才能读取 time.sleep(0.1) player.play() wholetime = mediaObject.get_duration() / 1000 * 1000 while 1: # 截取到0.1s精度,降低cpu占用, notwork fine for vlc # FIXME: get_time NOT WORK WELL, 只能精确到0.3s # t = player.get_position() * wholetime t = player.get_time() / 1000 * 1000 # sys.stdout.write(str(t) + '\r') sys.stdout.write('[' + time.strftime("%M:%S", time.localtime(t / 1000)) + '/' + time.strftime("%M:%S", time.localtime(wholetime / 1000)) + '] ') if t not in lrc_d: sys.stdout.flush() # 向后清除 # sys.stdout.write("\033[K") else: sys.stdout.write(color + lrc_d[t] + '\033[0m') sys.stdout.flush() # 向后清除 sys.stdout.write("\033[K") sys.stdout.write('\r') # 播放停止时退出 if t == wholetime: sys.exit(0) # 0.05s循环 time.sleep(0.05) with open(f_lrc) as f: lrc = f.read() lrc_d = lrc2dict(lrc) vlcInstance = vlc.Instance() player = vlcInstance.media_player_new() mediaObject = vlcInstance.media_new(f_mp3) player.set_media(mediaObject) colors = [ '\x1B[31m', # 红色 '\x1B[32m', # 绿色 '\x1B[33m', # 黄色 '\x1B[34m', # 蓝色 '\x1B[35m', # 紫色 '\x1B[36m', # 青色 '\x1B[37m' # 灰白 ] color = random.choice(colors) print_lrc(player, lrc_d, color) 【 在 Valar 的大作中提到: 】 : 顶!对了,请问楼主,别的论坛里,代码都可以直接复制粘贴到文本编辑器里,咱们论坛里的代码为什么选择复制,然后粘贴到文本编辑器里就变成很长一行了。你的这个代码也是,请问,怎么才能完整复制?O(∩_∩)O~