mirror of
https://github.com/beetbox/beets.git
synced 2026-02-10 09:25:42 +01:00
cleanup and docs
--HG-- extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%4095
This commit is contained in:
parent
dd7808acf7
commit
e26a57c82b
3 changed files with 64 additions and 23 deletions
0
beets/player/__init__.py
Normal file
0
beets/player/__init__.py
Normal file
|
|
@ -12,7 +12,6 @@ from beets import Library
|
|||
import sys
|
||||
|
||||
|
||||
|
||||
DEFAULT_PORT = 6600
|
||||
PROTOCOL_VERSION = '0.12.2'
|
||||
BUFSIZE = 1024
|
||||
|
|
@ -41,12 +40,10 @@ ERROR_PLAYER_SYNC = 55
|
|||
ERROR_EXIST = 56
|
||||
|
||||
|
||||
|
||||
def debug(msg):
|
||||
print >>sys.stderr, msg
|
||||
|
||||
|
||||
|
||||
class Server(object):
|
||||
"""A MPD-compatible music player server.
|
||||
|
||||
|
|
@ -96,15 +93,6 @@ class Server(object):
|
|||
"""
|
||||
return SuccessResponse()
|
||||
|
||||
class BGServer(Server):
|
||||
"""A `Server` using GStreamer to play audio and beets to store its
|
||||
library.
|
||||
"""
|
||||
|
||||
def __init__(self, host, port=DEFAULT_PORT, libpath='library.blb'):
|
||||
super(BGServer, self).__init__(host, port)
|
||||
self.library = Library(libpath)
|
||||
|
||||
class Connection(object):
|
||||
"""A connection between a client and the server. Handles input and
|
||||
output from and to the client.
|
||||
|
|
@ -181,8 +169,6 @@ class Connection(object):
|
|||
"""
|
||||
cls(client, server).run()
|
||||
|
||||
|
||||
|
||||
class Command(object):
|
||||
"""A command issued by the client for processing by the server.
|
||||
"""
|
||||
|
|
@ -250,8 +236,6 @@ class CommandList(list):
|
|||
|
||||
return out
|
||||
|
||||
|
||||
|
||||
class Response(object):
|
||||
"""A result of executing a single `Command`. A `Response` is
|
||||
iterable and consists of zero or more lines of response data
|
||||
|
|
@ -298,6 +282,21 @@ class SuccessResponse(Response):
|
|||
return RESP_OK
|
||||
|
||||
|
||||
class BGServer(Server):
|
||||
"""A `Server` using GStreamer to play audio and beets to store its
|
||||
library.
|
||||
"""
|
||||
|
||||
def __init__(self, host, port=DEFAULT_PORT, libpath='library.blb'):
|
||||
import gstplayer
|
||||
super(BGServer, self).__init__(host, port)
|
||||
self.library = Library(libpath)
|
||||
self.player = gstplayer.GstPlayer()
|
||||
|
||||
def run(self):
|
||||
super(BGServer, self).run()
|
||||
self.player.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
BGServer('0.0.0.0', 6600, 'library.blb').run()
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""A wrapper for the GStreamer Python bindings that exposes a simple
|
||||
music player.
|
||||
"""
|
||||
|
||||
import gst
|
||||
import sys
|
||||
import time
|
||||
|
|
@ -8,8 +12,27 @@ import thread
|
|||
import os
|
||||
|
||||
class GstPlayer(object):
|
||||
"""A music player abstracting GStreamer's Playbin element.
|
||||
|
||||
Create a player object, then call run() to start a thread with a
|
||||
runloop. Then call play_file to play music. Use player.playing
|
||||
to check whether music is currently playing.
|
||||
|
||||
A basic play queue is also implemented (just a Python list,
|
||||
player.queue, whose last element is next to play). To use it,
|
||||
just call enqueue() and then play(). When a track finishes and
|
||||
another is available on the queue, it is played automatically.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# set up the Gstreamer player
|
||||
"""Initialize a player.
|
||||
|
||||
Once the player has been created, call run() to begin the main
|
||||
runloop in a separate thread.
|
||||
"""
|
||||
|
||||
# Set up the Gstreamer player. From the pygst tutorial:
|
||||
# http://pygstdocs.berlios.de/pygst-tutorial/playbin.html
|
||||
self.player = gst.element_factory_make("playbin", "player")
|
||||
fakesink = gst.element_factory_make("fakesink", "fakesink")
|
||||
self.player.set_property("video-sink", fakesink)
|
||||
|
|
@ -17,14 +40,18 @@ class GstPlayer(object):
|
|||
bus.add_signal_watch()
|
||||
bus.connect("message", self._handle_message)
|
||||
|
||||
# set up our own stuff
|
||||
# Set up our own stuff.
|
||||
self.playing = False
|
||||
self.queue = []
|
||||
|
||||
def _get_state(self):
|
||||
"""Returns the current state flag of the playbin."""
|
||||
# gst's get_state function returns a 3-tuple; we just want the
|
||||
# status flag in position 1.
|
||||
return self.player.get_state()[1]
|
||||
|
||||
def _handle_message(self, bus, message):
|
||||
"""Callback for status updates from GStreamer."""
|
||||
if message.type == gst.MESSAGE_EOS:
|
||||
# file finished playing
|
||||
if self.queue:
|
||||
|
|
@ -40,20 +67,28 @@ class GstPlayer(object):
|
|||
self.playing = False
|
||||
|
||||
def play_file(self, path):
|
||||
"""Immediately begin playing the audio file at the given
|
||||
path.
|
||||
"""
|
||||
self.player.set_state(gst.STATE_NULL)
|
||||
self.player.set_property("uri", "file://" + path)
|
||||
self.player.set_state(gst.STATE_PLAYING)
|
||||
self.playing = True
|
||||
|
||||
def play(self):
|
||||
"""If paused, resume playback. Otherwise, start playing the
|
||||
queue.
|
||||
"""
|
||||
if self._get_state() == gst.STATE_PAUSED:
|
||||
self.player.set_state(gst.STATE_PLAYING)
|
||||
self.playing = True
|
||||
else:
|
||||
# presumably, nothing is playing
|
||||
self.play_file(self.queue.pop())
|
||||
# Nothing is playing. Start the queue.
|
||||
if self.queue:
|
||||
self.play_file(self.queue.pop())
|
||||
|
||||
def pause(self):
|
||||
"""Pause playback."""
|
||||
self.player.set_state(gst.STATE_PAUSED)
|
||||
self.playing = False
|
||||
|
||||
|
|
@ -61,6 +96,12 @@ class GstPlayer(object):
|
|||
self.queue[0:0] = [path] # push to front
|
||||
|
||||
def run(self):
|
||||
"""Start a new thread for the player.
|
||||
|
||||
Call this function before trying to play any music with
|
||||
play_file() or play().
|
||||
"""
|
||||
# If we don't use the MainLoop, messages are never sent.
|
||||
gobject.threads_init()
|
||||
def start():
|
||||
loop = gobject.MainLoop()
|
||||
|
|
@ -68,16 +109,17 @@ class GstPlayer(object):
|
|||
thread.start_new_thread(start, ())
|
||||
|
||||
def block(self):
|
||||
"""Block until we stop playing."""
|
||||
"""Block until playing finishes (the queue empties)."""
|
||||
while self.playing:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
path = sys.argv[1]
|
||||
# A very simple command-line player. Just give it names of audio
|
||||
# files on the command line; these are all queued and played.
|
||||
p = GstPlayer()
|
||||
for path in sys.argv[1:]:
|
||||
p.enqueue(os.path.abspath(os.path.expanduser(path)))
|
||||
p.run()
|
||||
p.play()
|
||||
p.block()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue