Skip to content

Commit a3177d2

Browse files
authored
Merge pull request #15 from mgoltzsche/extract-coverart-from-item
serve cover art that is embedded into audio file
2 parents 3d7641a + 8a3b05f commit a3177d2

File tree

4 files changed

+70
-33
lines changed

4 files changed

+70
-33
lines changed

beetsplug/beetstream/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def home():
3939
from beetsplug.beetstream.utils import *
4040
import beetsplug.beetstream.albums
4141
import beetsplug.beetstream.artists
42+
import beetsplug.beetstream.coverart
4243
import beetsplug.beetstream.dummy
4344
import beetsplug.beetstream.playlists
4445
import beetsplug.beetstream.search

beetsplug/beetstream/albums.py

-31
Original file line numberDiff line numberDiff line change
@@ -111,37 +111,6 @@ def get_album_list(version):
111111

112112
return Response(xml_to_string(root), mimetype='text/xml')
113113

114-
@app.route('/rest/getCoverArt', methods=["GET", "POST"])
115-
@app.route('/rest/getCoverArt.view', methods=["GET", "POST"])
116-
def cover_art_file():
117-
query_id = int(album_subid_to_beetid(request.values.get('id')) or -1)
118-
size = request.values.get('size')
119-
album = g.lib.get_album(query_id)
120-
121-
# Fallback on item id. Some apps use this
122-
if not album:
123-
item = g.lib.get_item(query_id)
124-
if item is not None and item.album_id is not None:
125-
album = g.lib.get_album(item.album_id)
126-
else:
127-
flask.abort(404)
128-
129-
if album and album.artpath:
130-
image_path = album.artpath.decode('utf-8')
131-
132-
if size is not None and int(size) > 0:
133-
size = int(size)
134-
with Image.open(image_path) as image:
135-
bytes_io = io.BytesIO()
136-
image = image.resize((size, size))
137-
image.convert('RGB').save(bytes_io, 'PNG')
138-
bytes_io.seek(0)
139-
return flask.send_file(bytes_io, mimetype='image/png')
140-
141-
return flask.send_file(image_path)
142-
else:
143-
return flask.abort(404)
144-
145114
@app.route('/rest/getGenres', methods=["GET", "POST"])
146115
@app.route('/rest/getGenres.view', methods=["GET", "POST"])
147116
def genres():

beetsplug/beetstream/coverart.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from beetsplug.beetstream.utils import *
2+
from beetsplug.beetstream import app
3+
from flask import g, request
4+
from io import BytesIO
5+
from PIL import Image
6+
import flask
7+
import os
8+
import subprocess
9+
import tempfile
10+
11+
@app.route('/rest/getCoverArt', methods=["GET", "POST"])
12+
@app.route('/rest/getCoverArt.view', methods=["GET", "POST"])
13+
def cover_art_file():
14+
id = request.values.get('id')
15+
size = request.values.get('size')
16+
album = None
17+
18+
if id[:len(ALBUM_ID_PREFIX)] == ALBUM_ID_PREFIX:
19+
album_id = int(album_subid_to_beetid(id) or -1)
20+
album = g.lib.get_album(album_id)
21+
else:
22+
item_id = int(song_subid_to_beetid(id) or -1)
23+
item = g.lib.get_item(item_id)
24+
25+
if item is not None:
26+
if item.album_id is not None:
27+
album = g.lib.get_album(item.album_id)
28+
if not album or not album.artpath:
29+
tmp_file = tempfile.NamedTemporaryFile(prefix='beetstream-cover-', suffix='.png')
30+
tmp_file_name = tmp_file.name
31+
try:
32+
tmp_file.close()
33+
subprocess.run(['ffmpeg', '-i', item.path, '-an', '-c:v',
34+
'copy', tmp_file_name,
35+
'-hide_banner', '-loglevel', 'error',])
36+
37+
return _send_image(tmp_file_name, size)
38+
finally:
39+
os.remove(tmp_file_name)
40+
41+
if album and album.artpath:
42+
image_path = album.artpath.decode('utf-8')
43+
44+
if size is not None and int(size) > 0:
45+
return _send_image(image_path, size)
46+
47+
return flask.send_file(image_path)
48+
else:
49+
return flask.abort(404)
50+
51+
def _send_image(path_or_bytesio, size):
52+
converted = BytesIO()
53+
img = Image.open(path_or_bytesio)
54+
55+
if size is not None and int(size) > 0:
56+
size = int(size)
57+
img = img.resize((size, size))
58+
59+
img.convert('RGB').save(converted, 'PNG')
60+
converted.seek(0)
61+
62+
return flask.send_file(converted, mimetype='image/png')

beetsplug/beetstream/utils.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def map_song(song):
150150
"track": song["track"],
151151
"year": song["year"],
152152
"genre": song["genre"],
153-
"coverArt": album_beetid_to_subid(str(song["album_id"])) or "",
153+
"coverArt": _cover_art_id(song),
154154
"size": os.path.getsize(path),
155155
"contentType": path_to_content_type(path),
156156
"suffix": song["format"].lower(),
@@ -179,7 +179,7 @@ def map_song_xml(xml, song):
179179
xml.set("track", str(song["track"]))
180180
xml.set("year", str(song["year"]))
181181
xml.set("genre", song["genre"])
182-
xml.set("coverArt", album_beetid_to_subid(str(song["album_id"])) or "")
182+
xml.set("coverArt", _cover_art_id(song)),
183183
xml.set("size", str(os.path.getsize(path)))
184184
xml.set("contentType", path_to_content_type(path))
185185
xml.set("suffix", song["format"].lower())
@@ -194,6 +194,11 @@ def map_song_xml(xml, song):
194194
if song["disc"]:
195195
xml.set("discNumber", str(song["disc"]))
196196

197+
def _cover_art_id(song):
198+
if song['album_id']:
199+
return album_beetid_to_subid(str(song['album_id']))
200+
return song_beetid_to_subid(str(song['id']))
201+
197202
def map_artist(artist_name):
198203
return {
199204
"id": artist_name_to_id(artist_name),

0 commit comments

Comments
 (0)