[Python]简易terminal歌词滚动播放器

时间:2024-02-26 09:26:21

  整合了网易云的一些API,想写一个terminal版的音乐播放器,但是还没有想好写成什么样子。

  暂时写了一个必须又的功能:带歌词滚动的播放器,用了pygame里的mixer来播放音乐。

  准备有时间的时候实现一下其他的功能。

 

 1 # -*- coding:utf-8 -*-
 2 import re
 3 import os
 4 import time
 5 import copy
 6 import threading
 7 import pygame
 8 from pygame import mixer
 9 import itertools
10 
11 def read_file(path):
12     if not os.path.exists(path):
13         print \'path : \\'\' + path + \'\\' not find.\'
14         return []
15     content = \'\'
16     try:
17         with open(path, \'r\') as fp:
18             content += reduce(lambda x, y: x + y, fp)
19     finally:
20         fp.close()
21     return content.split(\'\n\')
22 
23 class Lyrics:
24     TIME_AXIS_REGEXP = re.compile(\'\[(\d+)\:(\d+)\.(\d+)\]\')
25     DEL_TIME_AXIS_REGEXP = re.compile(\'\[\d+\:\d+\.\d+\](.*)\')
26 
27     def __init__(self, path):
28         self.path = path
29 
30     def _get_time_diff(self, line):
31         tm = map(lambda each: map(int, each), self.TIME_AXIS_REGEXP.findall(line))
32         tm = map(lambda each: each[0] * 60 * 1000 + each[1] * 1000 + each[2], tm)
33         return (tm[0], line)
34 
35     def _show_lyric(self, line):
36         print line
37 
38     def static_lyric(self, lyrics):
39         for line in lyrics:
40             self._show_lyric(line)
41 
42     def dynamic_lyric(self, lyrics):
43         for line in lyrics:
44             try:
45                 time.sleep(float(line[0]) / 1000.0)
46                 self._show_lyric(line[1])
47             except:
48                 pass
49         while mixer.music.get_busy() == True:
50             time.sleep(5)
51 
52     def get_lyric(self):
53         lyrics = read_file(self.path)
54         tmp_lyric = lyrics
55         lyrics = filter(lambda line: len(self.TIME_AXIS_REGEXP.findall(line))!=0, lyrics)
56         if len(lyrics) == 0:
57             return False, tmp_lyric
58         lyrics = map(self._get_time_diff, lyrics)
59         tmp_lyric = copy.deepcopy(lyrics[:-1])
60         tmp_lyric.insert(0, (0, \'\'))
61         lyrics = map(lambda x: (x[0][0]-x[1][0], x[0][1]), zip(lyrics, tmp_lyric))
62         lyrics = map(lambda x: (x[0], self.DEL_TIME_AXIS_REGEXP.findall(x[1])[0]), lyrics)
63         return True, lyrics
64 
65     def show_lyric(self):
66         play_option, lyrics = self.get_lyric()
67         if play_option == True:
68             self.dynamic_lyric(lyrics)
69         else:
70             self.static_lyric(lyrics)
71 
72 def play(mp3_path, lrc_path):
73     lyrics = Lyrics(lrc_path)
74     mixer.init()
75     track = mixer.music.load(mp3_path)
76     mixer.music.play(1)
77     t_lyric = threading.Thread(target=lyrics.show_lyric)
78     t_lyric.start()
79     t_lyric.join()
80 
81 def __main__():
82     play_list = [[\'./test1.mp3\',\'./test1.lrc\'], [\'./test2.mp3\',\'./test2,lrc\'], [\'./test3.mp3\',\'./test3.lrc\']]
83     play_list = itertools.cycle(play_list)
84     while True:
85         tmp = play_list.next()
86         play(tmp[0], tmp[1])
87 
88 if __name__ == \'__main__\':
89     __main__()