stone2083

Linux下基于命令行的音乐播放器

按照同事的话说,我是一个十足的命令控。
利用最近项目通宵发布的空闲时间中,写了一个命令行下的音乐播放器,以满足我在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)

下载

posted on 2011-04-17 19:32 stone2083 阅读(4249) 评论(4)  编辑  收藏 所属分类: python

Feedback

# re: Linux下基于命令行的音乐播放器 2011-04-20 10:03 greatghoul

哥们精神头很足呀,py写个基本功能的播放器竟然就这么点代码。  回复  更多评论   

# re: Linux下基于命令行的音乐播放器 2011-04-20 18:59 stone2083

@greatghoul
一直来自己动手,丰衣足食 :)
用py写一些小工具,确实是一种享受。太便捷了。  回复  更多评论   

# re: Linux下基于命令行的音乐播放器[未登录] 2014-07-21 13:12 John

能否做一个,监控无线路由比如TP,发现我的手机连接到WIFI就播放音乐,断开就停止播放。最终效果是我回家就自动播放音乐,离家就暂停。  回复  更多评论   

# re: Linux下基于命令行的音乐播放器 2014-07-21 14:16 stone2083

@John
有意思.
可以搞, 给个思路
利用局域网广播, 监听局域网内有机器, 一旦获得指定MAC(就是你手机的MAC地址)
调用lib, 播放音乐, 即可.  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: