返回信息流早上在控制台下用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)
这是一条镜像帖。来源:北邮人论坛 / python / #3516同步于 2014/9/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
一个支持LRC的终端播放器
reverland
2014/9/29镜像同步10 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
基于vlc重做了遍,pygame对mp3的支持太有限
https://asciinema.org/a/12843
现在终于像个播放器了……
【 在 qiukun 的大作中提到: 】
: Orz
顶!对了,请问楼主,别的论坛里,代码都可以直接复制粘贴到文本编辑器里,咱们论坛里的代码为什么选择复制,然后粘贴到文本编辑器里就变成很长一行了。你的这个代码也是,请问,怎么才能完整复制?O(∩_∩)O~
我这里可以复制粘帖……
试试手机版
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~