按照同事的话说,我是一个十足的命令控。
利用最近项目通宵发布的空闲时间中,写了一个命令行下的音乐播放器,以满足我在linux命令下的需求。
播放器利用技术:
Python+GST(
http://gstreamer.freedesktop.org/modules/gst-python.html)+Console解析
播放器自持操作:
1. 播放
2. 下一首
3. 上一首
4. 暂停
5. 查看播放列表信息
6. 查看当前播放信息
7. 停止(退出)
看一张截图:
通过分析meliae dump出来的内存信息,差不做占用2.5M内存,算的上比较小巧了。
对应代码:(需要安装py-gst,ubuntu下:sudo apt-get install python-gst0.10)
1 #!/usr/bin/env python
2
3 import gst
4 import gobject
5 import sys
6 #to avoid eclipse'warning
7 eval('gobject.threads_init()')
8 from threading import Thread
9
10 class AudioPlayer:
11
12 EVENT_PLAY_NEW = 1
13
14 def __init__(self, advisor):
15 self.main = gobject.MainLoop()
16 self.player = gst.element_factory_make('playbin', 'player')
17 self.index = -1
18 self.list = None
19 self.advisor = advisor
20
21 bus = self.player.get_bus()
22 bus.add_signal_watch()
23 bus.connect('message', self.on_message)
24
25 Thread(target=self.main.run).start()
26
27 def add_list(self , list=[]):
28 if list is None:
29 list = []
30 self.list = [(i, l.strip(), l[l.rfind('/') + 1:]) for (i, l) in enumerate(list)]
31
32 def play(self, index=None):
33 #play specified tracks
34 if 0 <= index < len(self.list):
35 self.index = index
36 self.player.set_state(gst.STATE_NULL)
37 self.player.set_property('uri', self.list[index][1])
38 self.player.set_state(gst.STATE_PLAYING)
39 if self.advisor:
40 self.advisor.on_message(AudioPlayer.EVENT_PLAY_NEW, (self.index, self.get_title()))
41 #resume playing
42 if index is None:
43 if self.index > -1:
44 self.player.set_state(gst.STATE_PLAYING)
45
46 def pause(self):
47 self.player.set_state(gst.STATE_PAUSED)
48
49 def stop(self):
50 self.player.set_state(gst.STATE_NULL)
51 self.main.quit()
52
53 def get_title(self):
54 if self.index == -1 or len(self.list) == 0:
55 return None
56 return self.list[self.index][2]
57
58 def get_previous(self):
59 if self.index == -1 or len(self.list) == 0:
60 return - 1
61 if self.index == 0:
62 return 0
63 return self.index - 1
64
65 def get_next(self):
66 if len(self.list) == 0:
67 return - 1
68 if self.index + 1 == len(self.list):
69 return 0
70 return self.index + 1
71
72 def on_message(self, bus, message):
73 t = message.type
74 if t == gst.MESSAGE_ERROR:
75 self.play(self.get_next())
76 elif t == gst.MESSAGE_EOS:
77 self.play(self.get_next())
78
79 class Console:
80
81 def __init__(self, list):
82 self.player = AudioPlayer(self)
83 self.player.add_list(list)
84 self.player.play(0)
85
86 Thread(target=self.run).start()
87
88 def run(self):
89 while(True):
90 self.on_cmd(raw_input())
91
92 def on_cmd(self, cmd):
93 if cmd is None:
94 return
95 if cmd.startswith('play'):
96 self.player.play()
97 elif cmd.startswith('next'):
98 self.player.play(self.player.get_next())
99 elif cmd.startswith('previous'):
100 self.player.play(self.player.get_previous())
101 elif cmd.startswith('pause'):
102 self.player.pause()
103 elif cmd.startswith('list'):
104 print '====================================='
105 for info in self.player.list:
106 print '%s. %s' % (info[0], info[2])
107 print '====================================='
108 elif cmd.startswith('info'):
109 print '====================================='
110 print '%s. %s' % (self.player.index, self.player.get_title())
111 print '====================================='
112 elif cmd.startswith('stop'):
113 self.player.stop()
114 sys.exit(0)
115 elif cmd.startswith('dump'):
116 from meliae import scanner
117 scanner.dump_all_objects('./dump.txt')
118 else:
119 print '''=====================================
120 Usage:
121 play
122 next
123 previous
124 pause
125 list
126 info
127 stop
128 dump
129 ====================================='''
130
131 def on_message(self, event, info):
132 if event == AudioPlayer.EVENT_PLAY_NEW:
133 print '====================================='
134 print 'Tracks: %s.%s' % (info[0], info[1])
135 print '====================================='
136
137
138 if len(sys.argv) != 2:
139 print 'player.py mp3.list'
140 sys.exit(-1)
141 list = [l.strip() for l in open(sys.argv[1]).readlines() if l.strip() != '']
142 Console(list)
下载