mirror of
https://codeberg.org/Hyperpipe/Hyperpipe
synced 2025-06-27 20:58:01 +02:00
Cleanup:
- smaller json structure for xml conv - fix minor typos and bugs in scripts/ - parallel fetching upto 2 concurrent segments
This commit is contained in:
parent
62e7cffbc4
commit
c7add3708e
15 changed files with 115 additions and 148 deletions
68
package-lock.json
generated
68
package-lock.json
generated
|
@ -13,7 +13,7 @@
|
|||
"mux.js": "^6.3.0",
|
||||
"peerjs": "^1.4.7",
|
||||
"pinia": "^2.1.6",
|
||||
"shaka-player": "^4.3.9",
|
||||
"shaka-player": "^4.4.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "^3.2.38"
|
||||
},
|
||||
|
@ -455,9 +455,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.13.tgz",
|
||||
"integrity": "sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==",
|
||||
"version": "7.22.14",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz",
|
||||
"integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==",
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
|
@ -1517,9 +1517,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/preset-env": {
|
||||
"version": "7.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.10.tgz",
|
||||
"integrity": "sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==",
|
||||
"version": "7.22.14",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.14.tgz",
|
||||
"integrity": "sha512-daodMIoVo+ol/g+//c/AH+szBkFj4STQUikvBijRGL72Ph+w+AMTSh55DUETe8KJlPlDT1k/mp7NBfOuiWmoig==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.22.9",
|
||||
|
@ -1548,41 +1548,41 @@
|
|||
"@babel/plugin-syntax-top-level-await": "^7.14.5",
|
||||
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
|
||||
"@babel/plugin-transform-arrow-functions": "^7.22.5",
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.22.10",
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.22.11",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.22.5",
|
||||
"@babel/plugin-transform-block-scoped-functions": "^7.22.5",
|
||||
"@babel/plugin-transform-block-scoping": "^7.22.10",
|
||||
"@babel/plugin-transform-class-properties": "^7.22.5",
|
||||
"@babel/plugin-transform-class-static-block": "^7.22.5",
|
||||
"@babel/plugin-transform-class-static-block": "^7.22.11",
|
||||
"@babel/plugin-transform-classes": "^7.22.6",
|
||||
"@babel/plugin-transform-computed-properties": "^7.22.5",
|
||||
"@babel/plugin-transform-destructuring": "^7.22.10",
|
||||
"@babel/plugin-transform-dotall-regex": "^7.22.5",
|
||||
"@babel/plugin-transform-duplicate-keys": "^7.22.5",
|
||||
"@babel/plugin-transform-dynamic-import": "^7.22.5",
|
||||
"@babel/plugin-transform-dynamic-import": "^7.22.11",
|
||||
"@babel/plugin-transform-exponentiation-operator": "^7.22.5",
|
||||
"@babel/plugin-transform-export-namespace-from": "^7.22.5",
|
||||
"@babel/plugin-transform-export-namespace-from": "^7.22.11",
|
||||
"@babel/plugin-transform-for-of": "^7.22.5",
|
||||
"@babel/plugin-transform-function-name": "^7.22.5",
|
||||
"@babel/plugin-transform-json-strings": "^7.22.5",
|
||||
"@babel/plugin-transform-json-strings": "^7.22.11",
|
||||
"@babel/plugin-transform-literals": "^7.22.5",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.22.5",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.22.11",
|
||||
"@babel/plugin-transform-member-expression-literals": "^7.22.5",
|
||||
"@babel/plugin-transform-modules-amd": "^7.22.5",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.22.5",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.22.11",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.22.11",
|
||||
"@babel/plugin-transform-modules-umd": "^7.22.5",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
|
||||
"@babel/plugin-transform-new-target": "^7.22.5",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.22.5",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.22.5",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.22.11",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.22.11",
|
||||
"@babel/plugin-transform-object-super": "^7.22.5",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.22.5",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.22.10",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.22.11",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.22.12",
|
||||
"@babel/plugin-transform-parameters": "^7.22.5",
|
||||
"@babel/plugin-transform-private-methods": "^7.22.5",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.22.5",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.22.11",
|
||||
"@babel/plugin-transform-property-literals": "^7.22.5",
|
||||
"@babel/plugin-transform-regenerator": "^7.22.10",
|
||||
"@babel/plugin-transform-reserved-words": "^7.22.5",
|
||||
|
@ -1596,7 +1596,7 @@
|
|||
"@babel/plugin-transform-unicode-regex": "^7.22.5",
|
||||
"@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
|
||||
"@babel/preset-modules": "0.1.6-no-external-plugins",
|
||||
"@babel/types": "^7.22.10",
|
||||
"@babel/types": "^7.22.11",
|
||||
"babel-plugin-polyfill-corejs2": "^0.4.5",
|
||||
"babel-plugin-polyfill-corejs3": "^0.8.3",
|
||||
"babel-plugin-polyfill-regenerator": "^0.5.2",
|
||||
|
@ -2170,9 +2170,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz",
|
||||
"integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==",
|
||||
"version": "20.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.8.tgz",
|
||||
"integrity": "sha512-eajsR9aeljqNhK028VG0Wuw+OaY5LLxYmxeoXynIoE6jannr9/Ucd1LL0hSSoafk5LTYG+FfqsyGt81Q6Zkybw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
|
@ -2556,9 +2556,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001524",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
|
||||
"integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
|
||||
"version": "1.0.30001525",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz",
|
||||
"integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2726,9 +2726,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.505",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz",
|
||||
"integrity": "sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ==",
|
||||
"version": "1.4.508",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz",
|
||||
"integrity": "sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/eme-encryption-scheme-polyfill": {
|
||||
|
@ -4387,9 +4387,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/shaka-player": {
|
||||
"version": "4.3.9",
|
||||
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.3.9.tgz",
|
||||
"integrity": "sha512-5rJe3IpYTzk83vmNhcaEmtjfSCf7gZP8OlDOLZyt5K20PgiY8sj4whv+JvvCx3PNS7d8ZheyQXv5c6aqV2m8gA==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.4.0.tgz",
|
||||
"integrity": "sha512-3tdj7iqytDjCctMZvqGm/9vTcdmK1ESTVxyG6Dtol8lRZuWlWb/FDqBYLb4PsywQh1mVa+OmvpGCHsRzUTDxiA==",
|
||||
"dependencies": {
|
||||
"eme-encryption-scheme-polyfill": "^2.1.1"
|
||||
},
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"mux.js": "^6.3.0",
|
||||
"peerjs": "^1.4.7",
|
||||
"pinia": "^2.1.6",
|
||||
"shaka-player": "^4.3.9",
|
||||
"shaka-player": "^4.4.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "^3.2.38"
|
||||
},
|
||||
|
|
|
@ -152,7 +152,7 @@ onMounted(() => {
|
|||
v-if="data.state.art"
|
||||
class="art"
|
||||
loading="lazy"
|
||||
:src="data.state.art.replaceAll('&', '&')" />
|
||||
:src="data.state.art" />
|
||||
|
||||
<div class="wrapper">
|
||||
<NowPlaying @get-artist="artist.getArtist" />
|
||||
|
@ -207,6 +207,7 @@ onMounted(() => {
|
|||
|
||||
<style>
|
||||
@import './assets/base.css';
|
||||
@import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"date": "2023-08-30"
|
||||
"date": "2023-09-02"
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@ async function getCharts() {
|
|||
console.log(json);
|
||||
|
||||
if (!id.value)
|
||||
id.value = json.options.all.find(i => store.cc ? i.id == store.cc : i.title == json.options.default).id;
|
||||
id.value = json.options.all.find(i =>
|
||||
store.cc ? i.id == store.cc : i.title == json.options.default,
|
||||
).id;
|
||||
|
||||
for (const country of json.options.all) {
|
||||
const locId = `countries.${country.id}`,
|
||||
|
|
|
@ -169,7 +169,7 @@ const setProxy = async () => {
|
|||
format: 'Hyperpipe',
|
||||
version: 0,
|
||||
app_version: 0,
|
||||
subscriptions: JSON.parse( store.subs || '[]' ).map(id => ({
|
||||
subscriptions: JSON.parse(store.subs || '[]').map(id => ({
|
||||
url: 'https://www.youtube.com/channel/' + id,
|
||||
service_id: 0,
|
||||
})),
|
||||
|
|
|
@ -75,6 +75,9 @@ async function Stream() {
|
|||
manifest: {
|
||||
disableVideo: true,
|
||||
},
|
||||
streaming: {
|
||||
segmentPrefetchLimit: 2,
|
||||
},
|
||||
});
|
||||
|
||||
window.audioPlayer = audioPlayer;
|
||||
|
@ -109,7 +112,7 @@ async function Stream() {
|
|||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
useAlert.add('error: ' + e.code)
|
||||
useAlert.add('error: ' + e.code);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ import { createPinia } from 'pinia';
|
|||
|
||||
import App from './App.vue';
|
||||
|
||||
import('bootstrap-icons/font/bootstrap-icons.css');
|
||||
|
||||
const pinia = createPinia(),
|
||||
app = createApp(App);
|
||||
|
||||
|
|
|
@ -12,64 +12,53 @@ export function useDash(streams, len) {
|
|||
else {
|
||||
mimeTypes.push(stream.mimeType);
|
||||
mimes.push([]);
|
||||
mimes[mimeTypes.length - 1].push(stream);
|
||||
mimes.at(-1).push(stream);
|
||||
}
|
||||
});
|
||||
|
||||
for (let i in mimeTypes) {
|
||||
const set = {
|
||||
type: 'element',
|
||||
name: 'AdaptationSet',
|
||||
attributes: {
|
||||
attr: {
|
||||
id: i,
|
||||
contentType: 'audio',
|
||||
mimeType: mimeTypes[i],
|
||||
startWithSAP: '1',
|
||||
subsegmentAlignment: 'true',
|
||||
},
|
||||
elements: [],
|
||||
child: [],
|
||||
};
|
||||
|
||||
mimes[i].forEach(format => {
|
||||
const audio = {
|
||||
type: 'element',
|
||||
name: 'Representation',
|
||||
attributes: {
|
||||
attr: {
|
||||
id: format.itag,
|
||||
codecs: format.codec,
|
||||
bandwidth: format.bitrate,
|
||||
},
|
||||
elements: [
|
||||
child: [
|
||||
{
|
||||
type: 'element',
|
||||
name: 'AudioChannelConfiguration',
|
||||
attributes: {
|
||||
attr: {
|
||||
schemeIdUri:
|
||||
'urn:mpeg:dash:23003:3:audio_channel_configuration:2011',
|
||||
value: '2',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
name: 'BaseURL',
|
||||
elements: [
|
||||
{
|
||||
type: 'text',
|
||||
text: format.url,
|
||||
},
|
||||
],
|
||||
child: [format.url],
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
name: 'SegmentBase',
|
||||
attributes: {
|
||||
attr: {
|
||||
indexRange: `${format.indexStart}-${format.indexEnd}`,
|
||||
},
|
||||
elements: [
|
||||
child: [
|
||||
{
|
||||
type: 'element',
|
||||
name: 'Initialization',
|
||||
attributes: {
|
||||
attr: {
|
||||
range: `${format.initStart}-${format.initEnd}`,
|
||||
},
|
||||
},
|
||||
|
@ -78,43 +67,31 @@ export function useDash(streams, len) {
|
|||
],
|
||||
};
|
||||
|
||||
set.elements.push(audio);
|
||||
set.child.push(audio);
|
||||
});
|
||||
|
||||
sets.push(set);
|
||||
}
|
||||
|
||||
const gen = {
|
||||
declaration: {
|
||||
attributes: {
|
||||
version: '1.0',
|
||||
encoding: 'utf-8',
|
||||
},
|
||||
},
|
||||
elements: [
|
||||
const gen = [
|
||||
{
|
||||
type: 'element',
|
||||
name: 'MPD',
|
||||
attributes: {
|
||||
attr: {
|
||||
xmlns: 'urn:mpeg:dash:schema:mpd:2011',
|
||||
profiles: 'urn:mpeg:dash:profile:full:2011',
|
||||
minBufferTime: 'PT1.5S',
|
||||
type: 'static',
|
||||
mediaPresentationDuration: `PT${len}S`,
|
||||
},
|
||||
elements: [
|
||||
child: [
|
||||
{
|
||||
type: 'element',
|
||||
name: 'Period',
|
||||
attributes: {
|
||||
id: 0,
|
||||
},
|
||||
elements: sets,
|
||||
attr: { id: 0 },
|
||||
child: sets,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
];
|
||||
|
||||
return useXML(gen);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ export function useSetupDB() {
|
|||
};
|
||||
|
||||
req.onerror = e => {
|
||||
console.log('Please let me use indexedDB!!');
|
||||
console.log(e);
|
||||
alert(e.target.error.message);
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
req.onsuccess = e => {
|
||||
|
@ -33,7 +31,7 @@ export function useUpdatePlaylist(key, obj, cb = () => null) {
|
|||
req = store.get(key);
|
||||
|
||||
req.onerror = e => {
|
||||
console.log('Error!!', e);
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
req.onsuccess = e => {
|
||||
|
@ -71,7 +69,7 @@ export function useCreatePlaylist(key, obj, cb = () => null) {
|
|||
|
||||
cb(res);
|
||||
} else {
|
||||
console.log(e.target.result);
|
||||
console.error(e.target.result);
|
||||
alert(`Error: Playlist with name ${key} exists`);
|
||||
}
|
||||
};
|
||||
|
@ -101,7 +99,7 @@ export function useGetPlaylist(key, cb = () => null) {
|
|||
req = store.get(key);
|
||||
|
||||
req.onerror = e => {
|
||||
console.log('Error!!', e);
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
req.onsuccess = e => {
|
||||
|
|
|
@ -56,7 +56,7 @@ export async function getJsonAuth(path, opts = {}) {
|
|||
return await fetch('https://' + root + path, opts)
|
||||
.then(res => res.json())
|
||||
.catch(err => {
|
||||
useAlert.add(err);
|
||||
useAlert().add(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import DOMPurify from 'dompurify';
|
||||
import { useI18n } from '@/stores/misc.js';
|
||||
|
||||
export const AMP = /&/g;
|
||||
export const PL_EXP =
|
||||
/[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}/;
|
||||
|
||||
export function useSanitize(txt) {
|
||||
return DOMPurify.sanitize(txt, {
|
||||
ALLOWED_TAGS: ['br'],
|
||||
|
@ -8,9 +12,7 @@ export function useSanitize(txt) {
|
|||
}
|
||||
|
||||
export function useVerifyAuth(hash) {
|
||||
return /[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}/.test(
|
||||
hash,
|
||||
);
|
||||
return PL_EXP.test(hash);
|
||||
}
|
||||
|
||||
export function useRoute(l) {
|
||||
|
@ -45,7 +47,7 @@ export function useStore() {
|
|||
export function useShare(data) {
|
||||
if ('share' in navigator) {
|
||||
navigator.share(data).catch(err => {
|
||||
console.err(err);
|
||||
console.error(err);
|
||||
});
|
||||
} else {
|
||||
const { t } = useI18n();
|
||||
|
@ -77,8 +79,6 @@ export function useMetadata(url, urls, data) {
|
|||
type: 'image/webp',
|
||||
}));
|
||||
} else if (data.art) artwork = [{ src: data.art, type: 'image/webp' }];
|
||||
|
||||
console.log(album, artwork);
|
||||
}
|
||||
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
|
@ -90,22 +90,22 @@ export function useMetadata(url, urls, data) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function useManifest(res) {
|
||||
export async function useManifest({ streams, duration, hls }) {
|
||||
let url, mime;
|
||||
|
||||
if (window.MediaSource !== undefined && res.streams.length > 0) {
|
||||
if (window.MediaSource !== undefined && streams.length > 0) {
|
||||
const { useDash } = await import('./dash.js');
|
||||
|
||||
const dash = useDash(res.streams, res.duration);
|
||||
const dash = useDash(streams, duration);
|
||||
|
||||
url = 'data:application/dash+xml;charset=utf-8;base64,' + btoa(dash);
|
||||
mime = 'application/dash+xml';
|
||||
} else if (res.hls) {
|
||||
url = res.hls;
|
||||
} else if (hls) {
|
||||
url = hls;
|
||||
mime = 'application/x-mpegURL';
|
||||
} else if (res.streams.length > 0) {
|
||||
url = res.streams[0].url;
|
||||
mime = res.streams[0].mimeType;
|
||||
} else if (streams.length > 0) {
|
||||
url = streams[0].url;
|
||||
mime = streams[0].mimeType;
|
||||
}
|
||||
|
||||
return { url, mime };
|
||||
|
|
|
@ -3,8 +3,7 @@ function useAttr(json) {
|
|||
|
||||
for (const attr in json) {
|
||||
if (json[attr] != null) {
|
||||
attrs += ' ';
|
||||
attrs += attr;
|
||||
attrs += ' ' + attr;
|
||||
attrs += '="';
|
||||
attrs += ('' + json[attr]).replace(/"/g, '"e;');
|
||||
attrs += '"';
|
||||
|
@ -18,22 +17,18 @@ function useElems(json) {
|
|||
let elems = '';
|
||||
|
||||
json.forEach(elem => {
|
||||
switch (elem.type) {
|
||||
case 'element':
|
||||
elems += '<';
|
||||
elems += elem.name;
|
||||
elems += useAttr(elem.attributes);
|
||||
switch (typeof elem) {
|
||||
case 'object':
|
||||
elems += '<' + elem.name + useAttr(elem.attr);
|
||||
|
||||
if (elem?.elements?.length > 0) {
|
||||
elems += '>';
|
||||
elems += useElems(elem.elements);
|
||||
elems += '</';
|
||||
elems += elem.name;
|
||||
if (elem?.child?.length > 0) {
|
||||
elems += '>';
|
||||
elems += useElems(elem.child);
|
||||
elems += '</' + elem.name + '>';
|
||||
} else elems += '/>';
|
||||
break;
|
||||
case 'text':
|
||||
elems += ('' + elem.text)
|
||||
case 'string':
|
||||
elems += ('' + elem)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/>/g, '>')
|
||||
|
@ -48,13 +43,8 @@ function useElems(json) {
|
|||
export function useXML(json) {
|
||||
json = JSON.parse(JSON.stringify(json));
|
||||
|
||||
let base = '';
|
||||
let xml = '<?xml version="1.0" encoding="utf-8" ?>';
|
||||
xml += useElems(json);
|
||||
|
||||
base += '<?xml';
|
||||
base += useAttr(json.declaration.attributes);
|
||||
base += '?>';
|
||||
|
||||
base += useElems(json.elements);
|
||||
|
||||
return base;
|
||||
return xml;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export const SUPPORTED_LOCALES = [
|
|||
{
|
||||
code: 'nl',
|
||||
name: 'Nederlands',
|
||||
cc: 'NL'
|
||||
cc: 'NL',
|
||||
},
|
||||
{
|
||||
code: 'pt',
|
||||
|
@ -162,10 +162,10 @@ export const useI18n = defineStore('i18n', () => {
|
|||
locale.value = code;
|
||||
localStorage.locale ??= code;
|
||||
if (localStorage.to_cc == 'true') {
|
||||
const cc = SUPPORTED_LOCALES.find(i => i.code == code).cc
|
||||
if (cc) localStorage.cc = cc
|
||||
else localStorage.cc = ''
|
||||
} else localStorage.cc = ''
|
||||
const cc = SUPPORTED_LOCALES.find(i => i.code == code).cc;
|
||||
if (cc) localStorage.cc = cc;
|
||||
else localStorage.cc = '';
|
||||
} else localStorage.cc = '';
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ export const useAlert = defineStore('alert', () => {
|
|||
|
||||
setTimeout(() => {
|
||||
if (msg.value == m) msg.value = '';
|
||||
}, 3000);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
return { msg, add };
|
||||
|
|
|
@ -2,7 +2,7 @@ import { reactive } from 'vue';
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
import { getJsonPiped, getJsonHyp } from '@/scripts/fetch.js';
|
||||
import { useStore, useMetadata } from '@/scripts/util.js';
|
||||
import { useStore, useMetadata, AMP } from '@/scripts/util.js';
|
||||
|
||||
const store = useStore();
|
||||
|
||||
|
@ -24,12 +24,10 @@ export const useData = defineStore('data', () => {
|
|||
const hash = new URLSearchParams(e.substring(e.indexOf('?'))).get('v'),
|
||||
json = await getJsonPiped('/streams/' + hash);
|
||||
|
||||
state.art = json.thumbnailUrl.replaceAll('&', '&');
|
||||
state.art = json.thumbnailUrl.replace(AMP, '&');
|
||||
state.description = json.description;
|
||||
state.title = json.title.replaceAll('&', '&');
|
||||
state.artist = json.uploader
|
||||
.replace(' - Topic', '')
|
||||
.replaceAll('&', '&');
|
||||
state.title = json.title.replace(AMP, '&');
|
||||
state.artist = json.uploader.replace(' - Topic', '').replace(AMP, '&');
|
||||
state.artistUrl = json.uploaderUrl;
|
||||
player.state.duration = json.duration;
|
||||
player.state.hls = json.hls;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue