Skip to content

Commit

Permalink
Persist Player Volume in global config + fix track refresh (Fixes #43)
Browse files Browse the repository at this point in the history
  • Loading branch information
yne committed Aug 17, 2024
1 parent f78e15a commit 3b54b2f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
12 changes: 7 additions & 5 deletions extension/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const fetch = (url, opt, data) => new Promise((resolve, reject) => {
// - not restful, so we can't infer it structure
// - /track/:id gives contributors but /search/track?q= don't
// - inconsistent listing structure (/playlist/:id => tracks.data, sometimes=>data, sometimes data.tracks)

// browse can be called from: user query / self list(from static menu) / self list(from fetch result)
async function browse(url_or_event_or_ids, label) {
try {
Expand Down Expand Up @@ -125,7 +126,7 @@ class DzrWebView { // can't Audio() in VSCode, we need a webview
this.statuses[1].text = this.state.ready ? label.length < 20 ? label : (label.slice(0, 20) + '…') : "$(play)"
this.statuses[2].text = this.state.ready && this.state.queue.length ? `${index + 1 || '?'}/${this.state.queue.length} $(chevron-right)` : null;//debug-step-over
this.treeView.description = (this.state.queue?.length ? `${index + 1 || '?'}/${this.state.queue.length}` : '') + ` loop:${this.state.looping}`;
this.treeView.message = this.state.queue?.length ? null : "Empty Queue. Add tracks to queue using '+'";
this.treeView.message = this.state.queue?.length ? null : "Empty Queue. Add tracks from the '+' menu";
}
async show(htmlUri, iconPath) {
if (this.panel) return this.panel.reveal(vscode.ViewColumn.One);
Expand All @@ -136,7 +137,7 @@ class DzrWebView { // can't Audio() in VSCode, we need a webview
});
this.panel.iconPath = iconPath;
this.panel.webview.html = (await vscode.workspace.fs.readFile(htmlUri)).toString();
this.panel.webview.onDidReceiveMessage((action, ...args) => this[action] ? this[action](...args) : this.badAction(action));
this.panel.webview.onDidReceiveMessage(([action, ...args]=[]) => this[action] ? this[action](...args) : this.badAction(action));
this.panel.onDidDispose(() => this.state.ready = this.panel = null);
this.post('state', this.state, Object.keys(this.state));
}
Expand All @@ -147,6 +148,7 @@ class DzrWebView { // can't Audio() in VSCode, we need a webview
this.waitAckSemaphore();
this.initAckSemaphore();
}
player_volumechange({volume}) { conf().update("volume", volume, vscode.ConfigurationTarget.Global); }
player_playing() { this.state.ready = this.state.playing = true; }
player_pause() { this.state.playing = false; }
player_ended() { vscode.commands.executeCommand('dzr.load', null); }
Expand Down Expand Up @@ -236,16 +238,16 @@ exports.activate = async function (/**@type {import('vscode').ExtensionContext}*
vscode.commands.executeCommand('dzr.show');
while (!dzr.state.ready) await wait();
}
dzr.state.current = dzr.state.queue[pos];
if ((dzr.state.current.expire || 0) < (new Date() / 1000)) {
if ((dzr.state.queue[pos].expire || 0) < (new Date() / 1000)) {
dzr.state.queue = await with_url(dzr.state.queue);//TODO: hope item is now up to date
}
dzr.state.current = dzr.state.queue[pos];
const hex = (str) => str.split('').map(c => c.charCodeAt(0))
const md5 = hex(crypto.createHash('md5').update(`${dzr.state.current.id}`).digest('hex'));
const key = Buffer.from(hex(conf().get('cbc')).map((c, i) => c ^ md5[i] ^ md5[i + 16]));
const iv = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7]);
const stripe = 2048;//TODO:use .pipe() API https://codereview.stackexchange.com/questions/57492/
dzr.post('open', dzr.state.current);
dzr.post('open', dzr.state.current, conf().get("volume"));
const buf_enc = await fetch(dzr.state.current.url);
for (let pos = 0; pos < buf_enc.length; pos += stripe) {
if ((pos >> 11) % 3) continue;
Expand Down
17 changes: 15 additions & 2 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,16 @@
},
"dzr.secure": {
"type": "boolean",
"default": true,
"default": false,
"description": "Disable if you are behind a corporate proxy"
},
"dzr.volume": {
"type": "number",
"default": 1,
"minimum": 0,
"maximum": 1,
"description": "Player volume [0..1], Applied at next track play"
},
"dzr.queue": {
"type": "array",
"default": [],
Expand All @@ -213,7 +220,7 @@
},
"dzr.menus": {
"type": "object",
"description": "API tree (this they endpoint are not RESTful)",
"description": "API tree (since deezer endpoint are not RESTful)",
"default": {
"_": [
{
Expand Down Expand Up @@ -328,6 +335,7 @@
"dzr.type2icon": {
"type": "object",
"description": "VSCode picker icon to display according to item type",
"additionalProperties": true,
"default": {
"track": "$(play-circle) ",
"artist": "$(person) ",
Expand All @@ -336,6 +344,11 @@
"radio": "$(broadcast) ",
"genre": "$(telescope) ",
"user": "$(account) "
},
"patternProperties": {
".*": {
"type": "string"
}
}
}
}
Expand Down
15 changes: 8 additions & 7 deletions extension/webview.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@ <h1>Disclamer</h1>
const title = document.getElementById('title');
const artists = document.getElementById('artists');
const cmd = (name, ...args) => `command:${name}?` + encodeURIComponent(JSON.stringify(args));
dialog.onclose=()=>{audio.play();post('user_interact');}
['ended', 'pause', 'playing'].map(on => audio.addEventListener(on, () => post('player_' + on)));
dialog.onclose=()=>{audio.play();post(['user_interact']);}
['ended', 'pause', 'playing', 'volumechange'].map(on => audio.addEventListener(on, () => post(['player_' + on, {volume:audio.volume}])));
let mediaSource, sourceBuffer;
const image = (type,md5,size=80) => `https://e-cdns-images.dzcdn.net/images/${type}/${md5}/${size}x${size}.jpg`
const on = {// event from VSCode
async open(item) {
async open(item,volume) {
mediaSource = new window.MediaSource();
audio.volume = volume;
audio.src = window.URL.createObjectURL(mediaSource);
await new Promise(then => mediaSource.onsourceopen = () => then());
sourceBuffer = mediaSource.addSourceBuffer("audio/mpeg");
sourceBuffer.addEventListener("updateend", (ev) => post('player_bufferized'));
sourceBuffer.addEventListener("updateend", (ev) => post(['player_bufferized']));
},
append(buf) { sourceBuffer.appendBuffer(buf) },
close() { mediaSource.endOfStream() },
play() { audio.play().catch(e=>post('error', e)) },
play() { audio.play().catch(e=>post(['error', `${e}`])) },
pause() { audio.pause() },
state(state, updates=[]) {
if (updates.includes('current')) {
Expand All @@ -50,15 +51,15 @@ <h1>Disclamer</h1>
artwork: [{ src: img.src, sizes: "1000x1000", type: "image/jpg" }]
});
}
}
},
};
window.addEventListener('message', ({ data: [cmd,...args] }) => {
if (!on[cmd]) return console.log("bad message:" + JSON.stringify([cmd,...args]));
on[cmd](...args);
});
navigator.mediaSession.setActionHandler("play", on.play);
navigator.mediaSession.setActionHandler("pause", on.pause);
navigator.mediaSession.setActionHandler("nexttrack", ()=>post('user_next'))
navigator.mediaSession.setActionHandler("nexttrack", ()=>post(['user_next']))
//navigator.mediaSession.setActionHandler("previoustrack", ()=>{})
</script>
<style>
Expand Down

0 comments on commit 3b54b2f

Please sign in to comment.