rind: Add an artwork widget
And look for the "image" tag from the gstreamer pipeline when setting. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
37c2260ebc
commit
d2c71f83a8
29
emmental.ui
29
emmental.ui
|
@ -438,7 +438,7 @@ audio-volume-medium-symbolic</property>
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="GtkPaned" id="sidebar_pane">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="position">180</property>
|
||||
|
@ -477,6 +477,31 @@ audio-volume-medium-symbolic</property>
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="album_artwork">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">image-missing</property>
|
||||
<property name="icon_size">5</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="artwork_separator">
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
|
@ -524,7 +549,7 @@ audio-volume-medium-symbolic</property>
|
|||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2019 (c) Anna Schumaker.
|
||||
from .. import gtk
|
||||
from gi.repository import GdkPixbuf
|
||||
|
||||
Image = gtk.Builder.get_object("album_artwork")
|
||||
Paned = gtk.Builder.get_object("sidebar_pane")
|
||||
Pixbuf = None
|
||||
Separator = gtk.Builder.get_object("artwork_separator")
|
||||
|
||||
def reset():
|
||||
Image.hide()
|
||||
Separator.hide()
|
||||
|
||||
def scale_image(new_w):
|
||||
new_h = (Pixbuf.get_height() * new_w) / Pixbuf.get_width()
|
||||
return Pixbuf.scale_simple(new_w, new_h, GdkPixbuf.InterpType.HYPER)
|
||||
|
||||
def set_image(data):
|
||||
global Pixbuf
|
||||
|
||||
loader = GdkPixbuf.PixbufLoader()
|
||||
loader.write(data)
|
||||
Pixbuf = loader.get_pixbuf()
|
||||
loader.close()
|
||||
|
||||
Image.set_from_pixbuf(scale_image(Paned.get_position() - 1))
|
||||
Image.show()
|
||||
Separator.show()
|
|
@ -1,4 +1,5 @@
|
|||
# Copyright 2019 (c) Anna Schumaker.
|
||||
from . import artwork
|
||||
from gi.repository import GLib, Gst
|
||||
|
||||
Playbin = Gst.ElementFactory.make("playbin")
|
||||
|
@ -27,6 +28,7 @@ def set_uri(uri, state=None):
|
|||
uri = GLib.filename_to_uri(uri)
|
||||
if state != None:
|
||||
Playbin.set_state(Gst.State.NULL)
|
||||
artwork.reset()
|
||||
set_property("uri", uri)
|
||||
if state != None:
|
||||
Playbin.set_state(state)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2019 (c) Anna Schumaker.
|
||||
from . import artwork
|
||||
from . import playbin
|
||||
from . import widgets
|
||||
from .. import gtk
|
||||
import os
|
||||
import unittest
|
||||
from gi.repository import Gtk, Gst
|
||||
|
||||
test_track = os.path.abspath("./trier/Test Album/01 - Test Track.ogg")
|
||||
|
||||
class TestAudioArtwork(unittest.TestCase):
|
||||
def setUp(self):
|
||||
playbin.reset()
|
||||
widgets.reset()
|
||||
|
||||
def test_artwork_init(self):
|
||||
self.assertIsInstance(artwork.Image, Gtk.Image)
|
||||
self.assertIsInstance(artwork.Paned, Gtk.Paned)
|
||||
self.assertIsInstance(artwork.Separator, Gtk.Separator)
|
||||
self.assertIsNone(artwork.Pixbuf)
|
||||
self.assertFalse(artwork.Image.is_visible())
|
||||
self.assertFalse(artwork.Separator.is_visible())
|
||||
|
||||
def test_artwork_load(self):
|
||||
artwork.Paned.set_position(150)
|
||||
playbin.set_uri(test_track, Gst.State.PAUSED)
|
||||
gtk.main_loop(delay=0.1)
|
||||
|
||||
self.assertTrue(artwork.Image.is_visible())
|
||||
self.assertTrue(artwork.Separator.is_visible())
|
||||
self.assertEqual(artwork.Image.get_storage_type(), Gtk.ImageType.PIXBUF)
|
||||
self.assertEqual(artwork.Pixbuf.get_height(), 512)
|
||||
self.assertEqual(artwork.Pixbuf.get_width(), 512)
|
||||
|
||||
pbuf = artwork.Image.get_pixbuf()
|
||||
self.assertEqual(pbuf.get_height(), 149)
|
||||
self.assertEqual(pbuf.get_width(), 149)
|
||||
|
||||
playbin.set_uri(test_track)
|
||||
self.assertFalse(artwork.Image.is_visible())
|
||||
self.assertFalse(artwork.Separator.is_visible())
|
|
@ -1,4 +1,5 @@
|
|||
# Copyright 2019 (c) Anna Schumaker.
|
||||
from . import artwork
|
||||
from . import autopause
|
||||
from . import playbin
|
||||
from .. import gtk
|
||||
|
@ -96,7 +97,13 @@ def set_tag_markup(label, text):
|
|||
label.set_markup(f"<big>{markup}</big>")
|
||||
|
||||
def on_each_tag(taglist, name):
|
||||
if name in [ "artist", "title" ]:
|
||||
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}")
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
# Copyright 2019 (c) Anna Schumaker.
|
||||
import base64
|
||||
import mutagen
|
||||
import mutagen.flac
|
||||
import mutagen.id3
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
trier = os.path.abspath("trier")
|
||||
ffmpeg = "ffmpeg -hide_banner -nostdin -f s16le -i /dev/zero -codec libvorbis -loglevel warning".split()
|
||||
|
||||
image = mutagen.flac.Picture()
|
||||
image.data = open("emmental.png", "rb").read()
|
||||
image.type = mutagen.id3.PictureType.COVER_FRONT
|
||||
image.mime = u"image/png"
|
||||
image.width = 512
|
||||
image.height = 512
|
||||
image.depth = 16
|
||||
encoded_data = base64.b64encode(image.write())
|
||||
image_data = encoded_data.decode("ascii")
|
||||
|
||||
|
||||
def generate_track(length, filename, tags={}):
|
||||
path = os.path.join(trier, filename)
|
||||
if os.path.exists(path):
|
||||
|
@ -16,6 +30,7 @@ def generate_track(length, filename, tags={}):
|
|||
fileinfo = mutagen.File(path)
|
||||
for (key, value) in tags.items():
|
||||
fileinfo[key] = value
|
||||
fileinfo["metadata_block_picture"] = [ image_data ]
|
||||
fileinfo.save()
|
||||
|
||||
# Create a bunch of tracks in the Test Album directory
|
||||
|
|
Loading…
Reference in New Issue