libsaria: Ported over Ocarina 5.0 audio functions

The new audio code I developed makes more sense and should be easier to
work with.  It makes sense to port it over.
This commit is contained in:
Bryan Schumaker 2011-04-30 12:06:48 -04:00
parent 9f0d8efbb7
commit 8574cda529
6 changed files with 382 additions and 244 deletions

View File

@ -16,6 +16,7 @@ if __dev__ == True:
__vers__ = "Libsaria %s" % __vstr__
import prefs
import audio
import event
import path
@ -25,18 +26,15 @@ from path.cache import Cache
cache = Cache()
#plugin = None
audio = None
lastfm = None
controls = None
# Initialize helpful variables
def init():
global audio
global lastfm
global controls
import audio
import controls
import sources
from path import lastfm
@ -54,7 +52,6 @@ def startup():
# import plugin
event.start("PRESTART")
audio.init()
controls.init2()
# plugin.load_all()
prefs.enable_save()

View File

@ -1,77 +1,163 @@
# Bryan Schumake (8/7/2010)
__all__ = ['audio']
import datetime
import threading
import pipeline
import gst
import libsaria
from libsaria import prefs
call = libsaria.event.call
expand = libsaria.path.expand
exists = libsaria.path.exists
audio = None
tdelta = None
timedelta = datetime.timedelta
audio_lock = threading.Lock()
lock_audio = audio_lock.acquire
unlock_audio = audio_lock.release
prefs.init("libsaria.audio.volume", 1.0)
def load_file(file):
lock_audio()
pipeline.load_file("file", file)
unlock_audio()
def init():
global tdelta
global audio
def get_state():
lock_audio()
state = pipeline.get_state()
unlock_audio()
return state
from datetime import timedelta as tdelta
import audio
audio.init()
def is_playing():
return get_state() == gst.STATE_PLAYING
#def do_notify_playing():
# if get_state() == gst.STATE_PLAYING:
# callback.play()
def end_of_song():
global audio
return call("EOS", audio.reset)
def play():
lock_audio()
pipeline.play()
unlock_audio()
#do_notify_playing()
#def do_notify_paused():
# if get_state() == gst.STATE_PAUSED:
# callback.pause()
def seek(prcnt):
global audio
return call("SEEK", audio.seek, prcnt)
def pause():
lock_audio()
pipeline.pause()
unlock_audio()
# do_notify_paused()
def stop():
lock_audio()
pipeline.stop()
unlock_audio()
#do_notify_paused()
def seek_sec(sec):
global audio
dur = audio.duration()
if dur > 0:
prcnt = get_progress() + (1 * sec * 1000000000) / audio.duration()
if prcnt > 1:
prcnt = 1
if prcnt < 0:
prcnt = 0
seek(prcnt)
def seek(amount):
lock_audio()
pipeline.seek(amount)
unlock_audio()
def position():
lock_audio()
pos = pipeline.position()
unlock_audio()
return pos
def duration():
lock_audio()
dur = pipeline.duration()
unlock_audio()
return dur
def get_progstr():
sec = position() / 1000000000
lenstr = "%s" % timedelta(seconds=sec)
if lenstr[0] == "0" and lenstr[1] == ":":
lenstr = lenstr[2:]
else:
lenstr = lenstr
return lenstr.split(".")[0]
def get_progress():
global audio
dur = audio.duration()
if dur > 0:
return audio.position() / dur
return 0
dur = duration()
if dur > 0.0:
return position() / dur
return 0.0
#def bus_message(bus, message):
# if message.type == gst.MESSAGE_EOS:
# source_proc.next()
#pipeline.bus.connect("message", bus_message)
#__all__ = ['audio']
#import gst
#import libsaria
#from libsaria import prefs
#call = libsaria.event.call
#expand = libsaria.path.expand
#exists = libsaria.path.exists
#audio = None
#tdelta = None
#prefs.init("libsaria.audio.volume", 1.0)
#def init():
#global tdelta
#global audio
#from datetime import timedelta as tdelta
#import audio
#audio.init()
def get_time():
global audio
global tdelta
if audio.get_state() == gst.STATE_NULL:
return ""
pos = audio.position()
pos /= 1000
time = str(tdelta(microseconds=pos))
time = time.rsplit('.', 1)[0]
time = time.split(':', 1)[1]
return time
#def end_of_song():
#global audio
#return call("EOS", audio.reset)
def get_time_at(prcnt):
duration = audio.duration()
if duration == 0:
return "00:00"
pos = duration * prcnt
pos /= 1000
time = str(tdelta(microseconds=pos))
time = time.rsplit('.', 1)[0]
time = time.split(':', 1)[1]
return time
#def seek(prcnt):
#global audio
#return call("SEEK", audio.seek, prcnt)
#def seek_sec(sec):
#global audio
#dur = audio.duration()
#if dur > 0:
#prcnt = get_progress() + (1 * sec * 1000000000) / audio.duration()
#if prcnt > 1:
#prcnt = 1
#if prcnt < 0:
#prcnt = 0
#seek(prcnt)
#def get_progress():
#global audio
#dur = audio.duration()
#if dur > 0:
#return audio.position() / dur
#return 0
#def get_time():
#global audio
#global tdelta
#if audio.get_state() == gst.STATE_NULL:
#return ""
#pos = audio.position()
#pos /= 1000
#time = str(tdelta(microseconds=pos))
#time = time.rsplit('.', 1)[0]
#time = time.split(':', 1)[1]
#return time
#def get_time_at(prcnt):
#duration = audio.duration()
#if duration == 0:
#return "00:00"
#pos = duration * prcnt
#pos /= 1000
#time = str(tdelta(microseconds=pos))
#time = time.rsplit('.', 1)[0]
#time = time.split(':', 1)[1]
#return time

View File

@ -1,195 +1,195 @@
# Bryan Schumaker (8/7/2010)
import libsaria
from libsaria import threads
#import libsaria
#from libsaria import threads
lock = threads.get_mutex("gstreamer")
gst = None
player = None
time = None
bus = None
length = None
call = libsaria.event.call
#lock = threads.get_mutex("gstreamer")
#gst = None
#player = None
#time = None
#bus = None
#length = None
#call = libsaria.event.call
# An init function for faster startup
def init():
global gst
global player
global time
global lock
import gst
## An init function for faster startup
#def init():
#global gst
#global player
#global time
#global lock
#import gst
lock.acquire()
player = gst.element_factory_make("playbin2", "player")
set_volume_locked(libsaria.prefs.get("libsaria.audio.volume"))
time = gst.Format(gst.FORMAT_TIME)
bus = player.get_bus()
bus.add_signal_watch()
bus.connect("message", on_message)
lock.release()
#lock.acquire()
#player = gst.element_factory_make("playbin2", "player")
#set_volume_locked(libsaria.prefs.get("libsaria.audio.volume"))
#time = gst.Format(gst.FORMAT_TIME)
#bus = player.get_bus()
#bus.add_signal_watch()
#bus.connect("message", on_message)
#lock.release()
def reset_locked():
global player
global length
player.set_state(gst.STATE_NULL)
length = None
def reset():
global lock
lock.acquire()
reset_locked()
lock.release()
def on_message(bus, message):
if message.type == gst.MESSAGE_EOS:
libsaria.audio.end_of_song()
def on_quit():
global lock
lock.acquire()
reset_locked()
lock.release()
libsaria.event.invite("PREQUIT", on_quit)
def get_state_locked():
global player
return player.get_state()[1]
def get_state():
global lock
lock.acquire()
state = get_state_locked()
lock.release()
return state
# Returns the length of the song in ms
def duration_locked():
global length
global player
global time
if get_state_locked() == gst.STATE_NULL:
return 0
if length == None:
try:
length = player.query_duration(time)[0]
except:
length = 0
return float(length)
def duration():
global lock
lock.acquire()
ret = duration_locked()
lock.release()
return ret
def position_locked():
global time
global player
if get_state_locked() == gst.STATE_NULL:
return float(0)
try:
pos = player.query_position(time)[0]
except:
pos = 0
return float(pos)
def position():
global lock
lock.acquire()
ret = position_locked()
lock.release()
return ret
def load_locked(file):
global gst
global player
reset_locked()
#def reset_locked():
#global player
#global length
#player.set_state(gst.STATE_NULL)
player.set_property("uri", "file://%s"%file)
player.set_state(gst.STATE_PAUSED)
return file
#length = None
def load(file):
global lock
lock.acquire()
ret = load_locked(file)
lock.release()
return ret
#def reset():
#global lock
#lock.acquire()
#reset_locked()
#lock.release()
def play_locked():
global gst
global player
player.set_state(gst.STATE_PLAYING)
return get_state_locked() == gst.STATE_PLAYING
def play():
global lock
lock.acquire()
ret = play_locked()
lock.release()
return ret
#def on_message(bus, message):
#if message.type == gst.MESSAGE_EOS:
#libsaria.audio.end_of_song()
def pause_locked():
global gst
global player
player.set_state(gst.STATE_PAUSED)
return get_state_locked() == gst.STATE_PAUSED
def pause():
global lock
lock.acquire()
ret = pause_locked()
lock.release()
return ret
def stop_locked():
pause_locked()
seek_locked(0)
return get_state_locked() == gst.STATE_PAUSED
def stop():
global lock
lock.acquire()
ret = stop_locked()
lock.release()
return ret
#def on_quit():
#global lock
#lock.acquire()
#reset_locked()
#lock.release()
#libsaria.event.invite("PREQUIT", on_quit)
def seek_locked(prcnt):
global player
global time
global gst
try:
spot = duration_locked() * prcnt
player.seek_simple(time, gst.SEEK_FLAG_FLUSH, spot)
except:
pass
#def get_state_locked():
#global player
#return player.get_state()[1]
def seek(prcnt):
global lock
lock.acquire()
seek_locked(prcnt)
lock.release()
#def get_state():
#global lock
#lock.acquire()
#state = get_state_locked()
#lock.release()
#return state
def set_volume_locked(prcnt):
global player
player.set_property("volume", prcnt)
libsaria.prefs.set("libsaria.audio.volume", prcnt)
return prcnt
## Returns the length of the song in ms
#def duration_locked():
#global length
#global player
#global time
#if get_state_locked() == gst.STATE_NULL:
#return 0
#if length == None:
#try:
#length = player.query_duration(time)[0]
#except:
#length = 0
#return float(length)
def set_volume(prcnt):
global lock
lock.acquire()
ret = set_volume_locked(prcnt)
lock.release()
return ret
#def duration():
#global lock
#lock.acquire()
#ret = duration_locked()
#lock.release()
#return ret
#def position_locked():
#global time
#global player
#if get_state_locked() == gst.STATE_NULL:
#return float(0)
#try:
#pos = player.query_position(time)[0]
#except:
#pos = 0
#return float(pos)
#def position():
#global lock
#lock.acquire()
#ret = position_locked()
#lock.release()
#return ret
#def load_locked(file):
#global gst
#global player
#reset_locked()
##player.set_state(gst.STATE_NULL)
#player.set_property("uri", "file://%s"%file)
#player.set_state(gst.STATE_PAUSED)
#return file
#def load(file):
#global lock
#lock.acquire()
#ret = load_locked(file)
#lock.release()
#return ret
#def play_locked():
#global gst
#global player
#player.set_state(gst.STATE_PLAYING)
#return get_state_locked() == gst.STATE_PLAYING
#def play():
#global lock
#lock.acquire()
#ret = play_locked()
#lock.release()
#return ret
#def pause_locked():
#global gst
#global player
#player.set_state(gst.STATE_PAUSED)
#return get_state_locked() == gst.STATE_PAUSED
#def pause():
#global lock
#lock.acquire()
#ret = pause_locked()
#lock.release()
#return ret
#def stop_locked():
#pause_locked()
#seek_locked(0)
#return get_state_locked() == gst.STATE_PAUSED
#def stop():
#global lock
#lock.acquire()
#ret = stop_locked()
#lock.release()
#return ret
#def seek_locked(prcnt):
#global player
#global time
#global gst
#try:
#spot = duration_locked() * prcnt
#player.seek_simple(time, gst.SEEK_FLAG_FLUSH, spot)
#except:
#pass
#def seek(prcnt):
#global lock
#lock.acquire()
#seek_locked(prcnt)
#lock.release()
#def set_volume_locked(prcnt):
#global player
#player.set_property("volume", prcnt)
#libsaria.prefs.set("libsaria.audio.volume", prcnt)
#return prcnt
#def set_volume(prcnt):
#global lock
#lock.acquire()
#ret = set_volume_locked(prcnt)
#lock.release()
#return ret

View File

@ -0,0 +1,57 @@
# Bryan Schumaker (2 / 6 / 2011)
# NOTE: DO NOT CALL FUNCTIONS IN THIS FILE DIRECTLY
# USE THE FUNCTIONS IN __init__.py INSTEAD. THIS
# WILL ENSURE THAT THE AUDIO LOCK IS HELD :-)
import gst
player = gst.element_factory_make("playbin2", "player")
time = gst.Format(gst.FORMAT_TIME)
bus = player.get_bus()
bus.add_signal_watch()
def reset():
player.set_state(gst.STATE_NULL)
def load_file(type, file):
reset()
player.set_property("uri", "%s://%s" % (type, file))
def play():
player.set_state(gst.STATE_PLAYING)
def pause():
player.set_state(gst.STATE_PAUSED)
def stop():
pause()
seek_to(0)
def get_state():
return player.get_state()[1]
def position():
if get_state() == gst.STATE_NULL:
pos = 0.0
else:
pos = player.query_position(time)[0]
return float(pos)
def duration():
if get_state() == gst.STATE_NULL:
dur = 0.0
else:
dur = player.query_duration(time)[0]
return float(dur)
def seek_to(new_spot):
if new_spot >= 0:
player.seek_simple(time, gst.SEEK_FLAG_FLUSH, new_spot)
def seek(amount):
pos = position()
if pos == 0.0:
return
seek_to( pos + (amount * 1000000000) )

View File

@ -1,13 +1,13 @@
# Bryan Schumaker (11/23/2010)
import prefs
import audio
libsaria = None
sources = None
library = None
playlist = None
queue = None
audio = None
call = None
invite = None
expand = None
@ -22,7 +22,6 @@ def init():
def init2():
global call
global audio
global invite
global sources
global library
@ -40,7 +39,6 @@ def init2():
playlist = sources.playlist
queue = sources.queue
from libsaria.audio import audio
invite("PREEOS", pause)
invite("POSTEOS", catch_eos)
@ -107,4 +105,4 @@ def load(file):
file = expand(file)
if not exists(file):
return False
return call("LOAD", audio.load, file)
return call("LOAD", audio.load_file, file)

View File

@ -19,7 +19,7 @@ footer.pack_start(detailed.detailed, True, True)
footer.show()
def update_pos():
time = audio.get_time()
time = audio.get_progstr()
tiny.update_pos(time)
detailed.update_pos(time)
return True