Moved to AGPLv3, Prefs for codec and audio quality

This commit is contained in:
Shiny Nematoda 2022-08-09 12:46:46 +00:00
parent 60167e45a7
commit 4ac524dcf2
No known key found for this signature in database
GPG key ID: 6506D50F5613A42D
8 changed files with 787 additions and 271 deletions

View file

@ -178,6 +178,8 @@ async function getArtist(e) {
console.log(json);
results.resetItems();
for (let i in json.items) {
results.setItem(i, { items: json.items[i] });
}
@ -310,6 +312,20 @@ onMounted(() => {
}
};
/* Media Controls */
navigator.mediaSession.setActionHandler('previoustrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
getSong(data.state.urls[i - 1].url);
}
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
getSong(data.state.urls[i + 1].url);
}
});
/* Setup IndexedDB for storing custom playlists */
useSetupDB();

View file

@ -1,5 +1,12 @@
<script setup>
import { ref, watch, onMounted, onUpdated } from 'vue';
import {
ref,
watch,
onMounted,
onUpdated,
onBeforeUnmount,
onUnmounted,
} from 'vue';
import muxjs from 'mux.js';
window.muxjs = muxjs;
@ -61,10 +68,10 @@ async function Stream() {
if (shaka.Player.isBrowserSupported) {
const audioPlayer = new shaka.Player(audio.value);
const codecs = [];
const codecs = useStore().getItem('codec');
audioPlayer.configure({
preferredAudioCodecs: ['opus', 'mp4a'],
preferredAudioCodecs: codecs ? codecs.split(':') : ['opus', 'mp4a'],
manifest: {
disableVideo: true,
},
@ -75,10 +82,45 @@ async function Stream() {
});
}
const quality = useStore().getItem('quality');
if (url) {
window.audioPlayer.load(url, 0, mime).catch(err => {
console.error('Code: ' + err.code, err);
});
window.audioPlayer
.load(url, 0, mime)
.then(() => {
if (quality && quality != 'auto') {
window.audioPlayer.configure('abr.enabled', false);
const tracks = window.audioPlayer.getVariantTracks();
let sel;
if (quality == 'best') {
let best = { bandwidth: 0 };
tracks.forEach(track => {
if (track.bandwidth > best.bandwidth) best = track;
});
sel = best;
} else if (quality == 'worst') {
let worst = { bandwidth: 10 ** 8 };
tracks.forEach(track => {
if (track.bandwidth < worst.bandwidth) worst = track;
});
sel = worst;
}
if (sel) {
window.audioPlayer.selectVariantTrack(sel);
}
}
})
.catch(err => {
console.error('Code: ' + err.code, err);
});
}
}
@ -124,19 +166,19 @@ onMounted(() => {
audio.value.pause();
player.state.status = 'play';
});
}
});
navigator.mediaSession.setActionHandler('previoustrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
getSong(data.state.urls[i - 1].url);
}
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
getSong(data.state.urls[i + 1].url);
}
});
onBeforeUnmount(() => {
if (window.audioPlayer) {
window.audioPlayer.destroy();
window.audioPlayer = undefined;
}
});
onUnmounted(() => {
if (window.audioPlayer) {
window.audioPlayer.destroy();
window.audioPlayer = undefined;
}
});
</script>

View file

@ -69,16 +69,6 @@ onMounted(() => {
<h2>Audio Player</h2>
<div class="left">
<input
type="checkbox"
name="pref-chk-hls"
id="pref-chk-hls"
@change="setStore('hls', $event.target.checked)"
v-model="hls" />
<label for="pref-chk-hls">Live Streaming</label>
</div>
<div class="left">
<input
type="checkbox"
@ -90,6 +80,34 @@ onMounted(() => {
</div>
<div class="left">
<label for="pref-codec">Codec</label>
<select
id="pref-codec"
name="pref-codec"
:value="getStore('codec') || 'opus:mp4a'"
@change="setStore('codec', $event.target.value)">
<option value="opus:mp4a">opus, mp4a</option>
<option value="mp4a:opus">mp4a, opus</option>
<option value="opus">opus</option>
<option value="mp4a">mp4a</option>
</select>
</div>
<div class="left">
<label for="pref-quality">Quality</label>
<select
id="pref-quality"
name="pref-quality"
:value="getStore('quality') || 'auto'"
@change="setStore('quality', $event.target.value)">
<option value="auto">auto</option>
<option value="best">best</option>
<option value="worst">worst</option>
</select>
</div>
<div class="left">
<label for="pref-volume">Default Volume</label>
<input
type="number"
name="pref-volume"
@ -98,7 +116,6 @@ onMounted(() => {
min="0"
:value="getStore('vol') || 100"
@change="setStore('vol', $event.target.value)" />
<label for="pref-volume">Default Volume</label>
</div>
<h2>Hyperpipe Instance</h2>
@ -237,6 +254,9 @@ label[for^='pref-chk'] {
margin: 0 auto;
padding: 1rem;
}
.left + .left {
padding: 0;
}
.table-wrap {
overflow-x: auto;
margin-bottom: 2rem;

View file

@ -116,6 +116,7 @@ function Save() {
showme.menu = !showme.menu;
player.state.playlist ? player.toggle('playlist') : '';
player.state.lyrics ? player.toggle('lyrics') : '';
player.state.info ? player.toggle('info') : '';
"></button>
<div id="menu" v-if="showme.menu" class="popup">
<button

View file

@ -1,7 +1,9 @@
import DOMPurify from 'dompurify';
export function useSanitize(txt) {
return DOMPurify.sanitize(txt);
return DOMPurify.sanitize(txt, {
ALLOWED_TAGS: ['br'],
});
}
export function useRoute(l) {