mirror of
https://codeberg.org/Hyperpipe/Hyperpipe
synced 2025-06-27 20:58:01 +02:00
Initial support for offline playback
This commit is contained in:
parent
1372d87beb
commit
4353cacead
9 changed files with 116 additions and 50 deletions
|
@ -93,12 +93,12 @@ function parseUrl() {
|
|||
|
||||
function playThis(t) {
|
||||
const i = data.state.urls.indexOf(t);
|
||||
data.getSong(data.state.urls[i].url);
|
||||
data.play(data.state.urls[i]);
|
||||
}
|
||||
|
||||
function playList(a) {
|
||||
data.state.urls = a;
|
||||
data.getSong(data.state.urls[0].url);
|
||||
data.play(data.state.urls[0]);
|
||||
}
|
||||
|
||||
/* Lifestyle hooks */
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"date": "2023-06-13"
|
||||
"date": "2023-06-20"
|
||||
}
|
||||
|
|
|
@ -75,10 +75,8 @@ const setProxy = async () => {
|
|||
title: 'Local • ' + key,
|
||||
items: res.urls.map(i => ({
|
||||
...i,
|
||||
...{
|
||||
playlistId: key,
|
||||
thumbnail: parseThumb(i.url, proxy.value),
|
||||
},
|
||||
playlistId: key,
|
||||
thumbnail: parseThumb(i.url, proxy.value),
|
||||
})),
|
||||
});
|
||||
|
||||
|
@ -86,6 +84,23 @@ const setProxy = async () => {
|
|||
} else alert('No songs to play!');
|
||||
});
|
||||
},
|
||||
OpenOffline = async () => {
|
||||
if (window.offline) {
|
||||
const songs = await window.offline.list();
|
||||
console.log();
|
||||
results.resetItems();
|
||||
results.setItem('songs', {
|
||||
title: 'Hyp • Offline',
|
||||
items: songs.map(i => ({
|
||||
...i.appMetadata,
|
||||
offlineUri: i.offlineUri,
|
||||
thumbnail: parseThumb(i.appMetadata.url, proxy.value),
|
||||
duration: i.duration
|
||||
})),
|
||||
});
|
||||
nav.state.page = 'home';
|
||||
}
|
||||
},
|
||||
List = async () => {
|
||||
if (!proxy.value) await setProxy();
|
||||
|
||||
|
@ -421,6 +436,7 @@ onMounted(async () => {
|
|||
<h2 v-if="list.length > 0">{{ t('playlist.local') }}</h2>
|
||||
|
||||
<div class="grid-3">
|
||||
<AlbumItem name="Offline" :grad="useRand()" @open-album="OpenOffline()" />
|
||||
<AlbumItem
|
||||
v-for="i in list"
|
||||
:key="i.name"
|
||||
|
|
|
@ -60,6 +60,18 @@ async function Stream() {
|
|||
}
|
||||
});
|
||||
|
||||
window.offline = new shaka.offline.Storage(audioPlayer);
|
||||
window.offline.configure({
|
||||
offline: {
|
||||
progressCallback: (data, prog) => console.log(data, prog),
|
||||
trackSelectionCallback: tracks => [
|
||||
tracks
|
||||
.sort((a, b) => a.bandwidth - b.bandwidth)
|
||||
.find(i => i.type == 'variant'),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
audioPlayer.configure({
|
||||
preferredAudioCodecs: codecs ? codecs.split(':') : ['opus', 'mp4a'],
|
||||
manifest: {
|
||||
|
@ -171,7 +183,7 @@ onMounted(() => {
|
|||
if (data.state.urls.length > 2) {
|
||||
const i = data.state.urls.findIndex(s => s.url == data.state.url);
|
||||
|
||||
data.getSong(data.state.urls[i - 1].url);
|
||||
data.play(data.state.urls[i - 1]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -179,7 +191,7 @@ onMounted(() => {
|
|||
if (data.state.urls.length > 2) {
|
||||
const i = data.state.urls.findIndex(s => s.url == data.state.url);
|
||||
|
||||
data.getSong(data.state.urls[i + 1].url);
|
||||
data.play(data.state.urls[i + 1]);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ const shuffleAdd = () => {
|
|||
url: i.url,
|
||||
title: i.title,
|
||||
thumbnails: [{ url: i.thumbnail }],
|
||||
thumbnail: i.thumbnail,
|
||||
offlineUri: i.offlineUri,
|
||||
duration: i.duration
|
||||
})),
|
||||
copy = [];
|
||||
|
||||
|
@ -56,9 +59,13 @@ const shuffleAdd = () => {
|
|||
url: i.url || '/watch?v=' + song.id,
|
||||
title: i.title,
|
||||
thumbnails: [{ url: i.thumbnail }],
|
||||
thumbnail: i.thumbnail,
|
||||
offlineUri: i.offlineUri,
|
||||
duration: i.duration
|
||||
}));
|
||||
|
||||
data.getSong(song.url || '/watch?v=' + song.id);
|
||||
song.url = song.url || '/watch?v=' + song.id;
|
||||
data.play(song);
|
||||
} else {
|
||||
emit('play-urls', [
|
||||
{
|
||||
|
@ -245,6 +252,9 @@ onDeactivated(() => {
|
|||
url: item.url,
|
||||
title: item.title,
|
||||
thumbnails: [{ url: item.thumbnail }],
|
||||
thumbnail: item.thumbnail,
|
||||
offlineUri: item.offlineUri,
|
||||
duration: item.duration
|
||||
})),
|
||||
)
|
||||
" />
|
||||
|
@ -313,9 +323,11 @@ onDeactivated(() => {
|
|||
:key="song.url || song.id"
|
||||
:index="index"
|
||||
:playlistId="song.playlistId"
|
||||
:author="song.uploaderName || song.subtitle"
|
||||
:author="song.uploaderName || song.artist || song.subtitle"
|
||||
:title="song.title || song.name"
|
||||
:channel="song.uploaderUrl || '/channel/' + song.subId"
|
||||
:channel="
|
||||
song.uploaderUrl || song.artistUrl || '/channel/' + song.subId
|
||||
"
|
||||
:play="song.url || '/watch?v=' + song.id"
|
||||
:art="
|
||||
song.thumbnail ||
|
||||
|
|
|
@ -75,6 +75,17 @@ function Save() {
|
|||
}
|
||||
}
|
||||
|
||||
async function Offline() {
|
||||
if (window.offline && data.state.url) {
|
||||
window.offline.store(window.audioPlayer.getAssetUri(), {
|
||||
title: data.state.title,
|
||||
url: data.state.url,
|
||||
artist: data.state.artist,
|
||||
artistUrl: data.state.artistUrl,
|
||||
});
|
||||
} else console.error('no offline storage found');
|
||||
}
|
||||
|
||||
async function Like() {
|
||||
liking.value = true;
|
||||
|
||||
|
@ -279,6 +290,12 @@ async function Like() {
|
|||
:data-loading="liking"
|
||||
@click="Like"></button>
|
||||
|
||||
<button
|
||||
id="dl-btn"
|
||||
title="Save for Offline Playback"
|
||||
class="bi bi-download clickable"
|
||||
@click="Offline"></button>
|
||||
|
||||
<button
|
||||
id="addToPlaylist"
|
||||
title="Add Current Song to a Playlist"
|
||||
|
|
|
@ -39,6 +39,15 @@ export const useData = defineStore('data', () => {
|
|||
await getNext(hash);
|
||||
}
|
||||
|
||||
async function play(song) {
|
||||
if (song.offlineUri) {
|
||||
state.art = song.thumbnail;
|
||||
player.state.duration = song.duration
|
||||
for (let i of ['title', 'artist', 'artistUrl', 'url']) state[i] = song[i];
|
||||
window.audioPlayer.load(song.offlineUri);
|
||||
} else await getSong(song.url);
|
||||
}
|
||||
|
||||
async function getNext(hash) {
|
||||
if (
|
||||
store.getItem('next') !== 'false' &&
|
||||
|
@ -97,34 +106,34 @@ export const useData = defineStore('data', () => {
|
|||
state.urls.length != 0 &&
|
||||
state.urls[i + 1]
|
||||
)
|
||||
getSong(state.urls[i + 1].url);
|
||||
play(state.urls[i + 1]);
|
||||
else if (player.state.loop == 1) {
|
||||
state.url = state.urls[0].url;
|
||||
getSong(state.urls[0].url);
|
||||
play(state.urls[0]);
|
||||
} else state.urls = [];
|
||||
}
|
||||
|
||||
function prevTrack() {
|
||||
const i = state.urls.findIndex(s => s.url === state.url);
|
||||
|
||||
if (state.urls[i - 1]) getSong(state.urls[i - 1].url);
|
||||
if (state.urls[i - 1]) play(state.urls[i - 1]);
|
||||
else if (player.state.loop == 1) {
|
||||
state.url = state.urls[state.urls.length - 1].url;
|
||||
getSong(state.urls[state.urls.length - 1].url);
|
||||
play(state.urls[state.urls.length - 1]);
|
||||
} else state.urls = [];
|
||||
}
|
||||
|
||||
function nextTrack() {
|
||||
const i = state.urls.findIndex(s => s.url === state.url);
|
||||
|
||||
if (state.urls[i + 1]) getSong(state.urls[i + 1].url);
|
||||
if (state.urls[i + 1]) play(state.urls[i + 1]);
|
||||
else if (player.state.loop == 1) {
|
||||
state.url = state.urls[0].url;
|
||||
getSong(state.urls[0].url);
|
||||
play(state.urls[0]);
|
||||
} else state.urls = [];
|
||||
}
|
||||
|
||||
return { state, getSong, playNext, prevTrack, nextTrack };
|
||||
return { state, getSong, play, playNext, prevTrack, nextTrack };
|
||||
});
|
||||
|
||||
export const usePlayer = defineStore('player', () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue