162 lines
4.6 KiB
Python
162 lines
4.6 KiB
Python
# Copyright 2019 (c) Anna Schumaker.
|
|
from . import artwork
|
|
from . import autopause
|
|
from . import playbin
|
|
from .. import gtk
|
|
import curds
|
|
from gi.repository import Gdk, GLib, Gst
|
|
|
|
NEXT_TRACK = None
|
|
SEEK_STEP = 10
|
|
|
|
|
|
def on_next(button):
|
|
track = NEXT_TRACK
|
|
if track == None:
|
|
track = curds.playlist.next()
|
|
if track != None:
|
|
playbin.set_uri(track.path, Gst.State.PLAYING)
|
|
|
|
Next = gtk.Builder.get_object("next_button")
|
|
Next.connect("clicked", on_next)
|
|
Next.connect("can-activate-accel", gtk.can_activate_accel)
|
|
|
|
def on_previous(button):
|
|
track = curds.playlist.previous()
|
|
if track != None:
|
|
playbin.set_uri(track.path, Gst.State.PLAYING)
|
|
|
|
Previous = gtk.Builder.get_object("previous_button")
|
|
Previous.connect("clicked", on_previous)
|
|
Previous.connect("can-activate-accel", gtk.can_activate_accel)
|
|
|
|
def on_play(button):
|
|
playbin.play()
|
|
|
|
Play = gtk.Builder.get_object("play_button")
|
|
Play.connect("clicked", on_play)
|
|
Play.connect("can-activate-accel", gtk.can_activate_accel)
|
|
|
|
def on_pause(button):
|
|
playbin.pause()
|
|
|
|
Pause = gtk.Builder.get_object("pause_button")
|
|
Pause.connect("clicked", on_pause)
|
|
Pause.connect("can-activate-accel", gtk.can_activate_accel)
|
|
|
|
def on_seek(range, scroll, value):
|
|
playbin.seek_percent(value)
|
|
|
|
Progress = gtk.Builder.get_object("progress_scale")
|
|
Progress.connect("change-value", on_seek)
|
|
|
|
def on_key_press(widget, event):
|
|
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
|
key = Gdk.keyval_name(event.keyval)
|
|
if ctrl and key in ("Left", "Right"):
|
|
step = SEEK_STEP if key == "Right" else -SEEK_STEP
|
|
playbin.seek_step(step)
|
|
return True
|
|
return False
|
|
|
|
gtk.Window.connect("key-press-event", on_key_press)
|
|
|
|
def on_volume_changed(button, value):
|
|
playbin.set_volume(value)
|
|
|
|
Volume = gtk.Builder.get_object("volume_button")
|
|
Volume.connect("value-changed", on_volume_changed)
|
|
|
|
|
|
Title = gtk.Builder.get_object("title")
|
|
Artist = gtk.Builder.get_object("artist")
|
|
|
|
def on_eos(message):
|
|
track = curds.playlist.next()
|
|
if track != None:
|
|
state = autopause.decrement()
|
|
playbin.set_uri(track.path, state)
|
|
|
|
def on_state_change(message):
|
|
if message.src == playbin.Playbin:
|
|
(old, new, pending) = message.parse_state_changed()
|
|
Play.set_visible( new != Gst.State.PLAYING)
|
|
Pause.set_visible(new == Gst.State.PLAYING)
|
|
if new != Gst.State.PLAYING and new != Gst.State.PAUSED:
|
|
set_tag_markup(Title, "Emmental")
|
|
set_tag_markup(Artist, "The Cheesy Music Player")
|
|
autopause.state_changed(new)
|
|
|
|
def on_stream_start(message):
|
|
global NEXT_TRACK
|
|
NEXT_TRACK = None
|
|
curds.notify.notify("stream-start")
|
|
|
|
def set_tag_markup(label, text):
|
|
markup = GLib.markup_escape_text(text)
|
|
label.set_markup(f"<big>{markup}</big>")
|
|
|
|
def on_each_tag(taglist, name):
|
|
if name == "image":
|
|
(res, sample) = taglist.get_sample(name)
|
|
buffer = sample.get_buffer()
|
|
(res, map) = buffer.map(Gst.MapFlags.READ)
|
|
artwork.set_image(map.data)
|
|
buffer.unmap(map)
|
|
elif name in [ "artist", "title" ]:
|
|
(valid, value) = taglist.get_string(name)
|
|
if valid and name == "artist":
|
|
set_tag_markup(Artist, f"by {value}")
|
|
elif valid and name == "title":
|
|
set_tag_markup(Title, value)
|
|
|
|
def on_message(bus, message):
|
|
if message.type == Gst.MessageType.EOS:
|
|
on_eos(message)
|
|
elif message.type == Gst.MessageType.STATE_CHANGED:
|
|
on_state_change(message)
|
|
elif message.type == Gst.MessageType.STREAM_START:
|
|
on_stream_start(message)
|
|
elif message.type == Gst.MessageType.TAG:
|
|
message.parse_tag().foreach(on_each_tag)
|
|
|
|
playbin.Bus.connect("message", on_message)
|
|
|
|
|
|
def on_about_to_finish(pbin):
|
|
global NEXT_TRACK
|
|
if not autopause.about_to_pause():
|
|
NEXT_TRACK = curds.playlist.next()
|
|
if NEXT_TRACK:
|
|
playbin.set_uri(NEXT_TRACK.path)
|
|
autopause.decrement()
|
|
|
|
playbin.Playbin.connect("about-to-finish", on_about_to_finish)
|
|
|
|
|
|
Position = gtk.Builder.get_object("position")
|
|
Remaining = gtk.Builder.get_object("remaining")
|
|
|
|
def timestr(nanoseconds):
|
|
(m, s) = divmod(round(nanoseconds / Gst.SECOND), 60)
|
|
return f"{m:02}:{s:02}"
|
|
|
|
def on_timeout():
|
|
Position.set_text( timestr(playbin.position()))
|
|
Remaining.set_text(timestr(playbin.remaining()))
|
|
Progress.get_adjustment().set_value(playbin.progress())
|
|
return GLib.SOURCE_CONTINUE
|
|
GLib.timeout_add(100, on_timeout)
|
|
|
|
|
|
def reset():
|
|
global NEXT_TRACK
|
|
global SEEK_STEP
|
|
set_tag_markup(Title, "Emmental")
|
|
set_tag_markup(Artist, "The Cheesy Music Player")
|
|
Play.show()
|
|
Pause.hide()
|
|
Volume.set_value(100)
|
|
NEXT_TRACK = None
|
|
SEEK_STEP = 10
|