diff --git a/emmental.ui b/emmental.ui index 4723d0e..93c991d 100644 --- a/emmental.ui +++ b/emmental.ui @@ -438,7 +438,7 @@ audio-volume-medium-symbolic True False - + True True 180 @@ -477,6 +477,31 @@ audio-volume-medium-symbolic 1 + + + False + image-missing + 5 + + + + False + True + 2 + + + + + False + + + False + True + 3 + + True @@ -524,7 +549,7 @@ audio-volume-medium-symbolic True True - 2 + 4 diff --git a/rind/audio/artwork.py b/rind/audio/artwork.py new file mode 100644 index 0000000..56b523d --- /dev/null +++ b/rind/audio/artwork.py @@ -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() diff --git a/rind/audio/playbin.py b/rind/audio/playbin.py index ca0143d..01664ca 100644 --- a/rind/audio/playbin.py +++ b/rind/audio/playbin.py @@ -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) diff --git a/rind/audio/test_artwork.py b/rind/audio/test_artwork.py new file mode 100644 index 0000000..9f92bc4 --- /dev/null +++ b/rind/audio/test_artwork.py @@ -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()) diff --git a/rind/audio/widgets.py b/rind/audio/widgets.py index 87ef2e8..f7d3aab 100644 --- a/rind/audio/widgets.py +++ b/rind/audio/widgets.py @@ -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"{markup}") 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}") diff --git a/trier/generate_tracks.py b/trier/generate_tracks.py index c8a58ad..5d3ef58 100644 --- a/trier/generate_tracks.py +++ b/trier/generate_tracks.py @@ -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