cyp/app/js/art.js

66 lines
1.7 KiB
JavaScript
Raw Permalink Normal View History

2019-03-22 22:35:04 +08:00
import * as html from "./html.js";
2020-03-10 05:24:31 +08:00
import * as conf from "./conf.js";
2019-03-20 05:56:39 +08:00
2020-03-14 06:01:16 +08:00
const cache = {};
2019-03-21 17:53:38 +08:00
const MIME = "image/jpeg";
2019-03-22 23:17:10 +08:00
const STORAGE_PREFIX = `art-${conf.artSize}` ;
2019-03-21 17:53:38 +08:00
function store(key, data) {
localStorage.setItem(`${STORAGE_PREFIX}-${key}`, data);
}
function load(key) {
return localStorage.getItem(`${STORAGE_PREFIX}-${key}`);
}
2019-03-20 05:56:39 +08:00
async function bytesToImage(bytes) {
2020-03-14 06:01:16 +08:00
const blob = new Blob([bytes]);
const src = URL.createObjectURL(blob);
const image = html.node("img", {src});
2019-03-20 05:56:39 +08:00
return new Promise(resolve => {
image.onload = () => resolve(image);
});
}
2019-03-21 17:53:38 +08:00
function resize(image) {
2020-06-23 15:23:14 +08:00
while (Math.min(image.width, image.height) >= 2*conf.artSize) {
let tmp = html.node("canvas", {width:image.width/2, height:image.height/2});
tmp.getContext("2d").drawImage(image, 0, 0, tmp.width, tmp.height);
image = tmp;
}
2020-03-14 06:01:16 +08:00
const canvas = html.node("canvas", {width:conf.artSize, height:conf.artSize});
2020-06-23 15:23:14 +08:00
canvas.getContext("2d").drawImage(image, 0, 0, canvas.width, canvas.height);
2019-03-21 17:53:38 +08:00
return canvas;
2019-03-20 05:56:39 +08:00
}
2020-03-13 17:52:03 +08:00
export async function get(mpd, artist, album, songUrl = null) {
2020-03-14 06:01:16 +08:00
const key = `${artist}-${album}`;
2019-03-20 23:20:17 +08:00
if (key in cache) { return cache[key]; }
2020-03-14 06:01:16 +08:00
const loaded = await load(key);
2019-03-21 17:53:38 +08:00
if (loaded) {
cache[key] = loaded;
return loaded;
}
2019-03-20 23:20:17 +08:00
if (!songUrl) { return null; }
// promise to be returned in the meantime
let resolve;
2020-03-14 06:01:16 +08:00
const promise = new Promise(res => resolve = res);
2019-03-20 23:20:17 +08:00
cache[key] = promise;
2020-03-14 06:01:16 +08:00
const data = await mpd.albumArt(songUrl);
if (data) {
const bytes = new Uint8Array(data);
const image = await bytesToImage(bytes);
const url = resize(image).toDataURL(MIME);
2019-03-21 17:53:38 +08:00
store(key, url);
2019-03-20 23:20:17 +08:00
cache[key] = url;
resolve(url);
2020-03-14 06:01:16 +08:00
} else {
2019-03-20 23:20:17 +08:00
cache[key] = null;
}
return cache[key];
2019-03-20 05:56:39 +08:00
}