no longer rely on plyr for playing videos instead use native video element
This commit is contained in:
parent
dcc5cd0a0b
commit
931ad0c5c5
5 changed files with 731 additions and 745 deletions
60
Pipfile.lock
generated
60
Pipfile.lock
generated
|
|
@ -27,11 +27,11 @@
|
|||
},
|
||||
"aiohappyeyeballs": {
|
||||
"hashes": [
|
||||
"sha256:147ec992cf873d74f5062644332c539fcd42956dc69453fe5204195e560517e1",
|
||||
"sha256:9b05052f9042985d32ecbe4b59a77ae19c006a78f1344d7fdad69d28ded3d0b0"
|
||||
"sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62",
|
||||
"sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==2.4.6"
|
||||
"version": "==2.4.8"
|
||||
},
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
|
|
@ -453,36 +453,36 @@
|
|||
},
|
||||
"debugpy": {
|
||||
"hashes": [
|
||||
"sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06",
|
||||
"sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180",
|
||||
"sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6",
|
||||
"sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d",
|
||||
"sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5",
|
||||
"sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969",
|
||||
"sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1",
|
||||
"sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb",
|
||||
"sha256:557cc55b51ab2f3371e238804ffc8510b6ef087673303890f57a24195d096e61",
|
||||
"sha256:5cc45235fefac57f52680902b7d197fb2f3650112379a6fa9aa1b1c1d3ed3f02",
|
||||
"sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce",
|
||||
"sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f",
|
||||
"sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498",
|
||||
"sha256:88a77f422f31f170c4b7e9ca58eae2a6c8e04da54121900651dfa8e66c29901a",
|
||||
"sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9",
|
||||
"sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9",
|
||||
"sha256:9af40506a59450f1315168d47a970db1a65aaab5df3833ac389d2899a5d63b3f",
|
||||
"sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7",
|
||||
"sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a",
|
||||
"sha256:a4042edef80364239f5b7b5764e55fd3ffd40c32cf6753da9bda4ff0ac466018",
|
||||
"sha256:b0232cd42506d0c94f9328aaf0d1d0785f90f87ae72d9759df7e5051be039738",
|
||||
"sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c",
|
||||
"sha256:b5c6c967d02fee30e157ab5227706f965d5c37679c687b1e7bbc5d9e7128bd41",
|
||||
"sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45",
|
||||
"sha256:f30b03b0f27608a0b26c75f0bb8a880c752c0e0b01090551b9d87c7d783e2069",
|
||||
"sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c"
|
||||
"sha256:06859f68e817966723ffe046b896b1bd75c665996a77313370336ee9e1de3e90",
|
||||
"sha256:2b8de94c5c78aa0d0ed79023eb27c7c56a64c68217d881bee2ffbcb13951d0c1",
|
||||
"sha256:31abc9618be4edad0b3e3a85277bc9ab51a2d9f708ead0d99ffb5bb750e18503",
|
||||
"sha256:32b6857f8263a969ce2ca098f228e5cc0604d277447ec05911a8c46cf3e7e307",
|
||||
"sha256:3872ce5453b17837ef47fb9f3edc25085ff998ce63543f45ba7af41e7f7d370f",
|
||||
"sha256:3dae443739c6b604802da9f3e09b0f45ddf1cf23c99161f3a1a8039f61a8bb89",
|
||||
"sha256:46abe0b821cad751fc1fb9f860fb2e68d75e2c5d360986d0136cd1db8cad4428",
|
||||
"sha256:4caca674206e97c85c034c1efab4483f33971d4e02e73081265ecb612af65377",
|
||||
"sha256:5268ae7fdca75f526d04465931cb0bd24577477ff50e8bb03dab90983f4ebd02",
|
||||
"sha256:62f9b4a861c256f37e163ada8cf5a81f4c8d5148fc17ee31fb46813bd658cdcc",
|
||||
"sha256:63ca7670563c320503fea26ac688988d9d6b9c6a12abc8a8cf2e7dd8e5f6b6ea",
|
||||
"sha256:6fab771639332bd8ceb769aacf454a30d14d7a964f2012bf9c4e04c60f16e85b",
|
||||
"sha256:79ce4ed40966c4c1631d0131606b055a5a2f8e430e3f7bf8fd3744b09943e8e8",
|
||||
"sha256:7d9a05efc6973b5aaf076d779cf3a6bbb1199e059a17738a2aa9d27a53bcc888",
|
||||
"sha256:837e7bef95bdefba426ae38b9a94821ebdc5bea55627879cd48165c90b9e50ce",
|
||||
"sha256:887d54276cefbe7290a754424b077e41efa405a3e07122d8897de54709dbe522",
|
||||
"sha256:924464d87e7d905eb0d79fb70846558910e906d9ee309b60c4fe597a2e802590",
|
||||
"sha256:a0bd87557f97bced5513a74088af0b84982b6ccb2e254b9312e29e8a5c4270eb",
|
||||
"sha256:acf39a6e98630959763f9669feddee540745dfc45ad28dbc9bd1f9cd60639391",
|
||||
"sha256:cb56c2db69fb8df3168bc857d7b7d2494fed295dfdbde9a45f27b4b152f37520",
|
||||
"sha256:d4ba115cdd0e3a70942bd562adba9ec8c651fe69ddde2298a1be296fc331906f",
|
||||
"sha256:dc7b77f5d32674686a5f06955e4b18c0e41fb5a605f5b33cf225790f114cfeec",
|
||||
"sha256:ea869fe405880327497e6945c09365922c79d2a1eed4c3ae04d77ac7ae34b2b5",
|
||||
"sha256:ed93c3155fc1f888ab2b43626182174e457fc31b7781cd1845629303790b8ad1",
|
||||
"sha256:eee02b2ed52a563126c97bf04194af48f2fe1f68bb522a312b05935798e922ff",
|
||||
"sha256:f14d2c4efa1809da125ca62df41050d9c7cd9cb9e380a2685d1e453c4d450ccb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==1.8.12"
|
||||
"version": "==1.8.13"
|
||||
},
|
||||
"frozenlist": {
|
||||
"hashes": [
|
||||
|
|
|
|||
|
|
@ -1,24 +1,16 @@
|
|||
<style>
|
||||
:root {
|
||||
--plyr-captions-background: rgba(0, 0, 0, 0.6);
|
||||
--plyr-captions-text-color: #f3db4d;
|
||||
--webkit-text-track-display: none;
|
||||
}
|
||||
|
||||
.plyr__caption {
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.plyr--full-ui ::-webkit-media-text-track-container {
|
||||
display: var(--webkit-text-track-display);
|
||||
<style scoped>
|
||||
.player {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<video id="player" ref="video" :poster="thumbnail" :title="title" playsinline>
|
||||
<video class="player" ref="video" :poster="thumbnail" :title="title" playsinline controls crossorigin="anonymous"
|
||||
preload="auto">
|
||||
<source v-for="source in sources" :key="source.src" :src="source.src" @error="source.onerror"
|
||||
:type="source.type" />
|
||||
<track v-for="track in tracks" :key="track.file" :kind="track.kind" :label="track.label" :srclang="track.lang"
|
||||
|
|
@ -28,18 +20,17 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { onMounted, onUpdated, ref, onUnmounted } from 'vue'
|
||||
import Hls from 'hls.js'
|
||||
import Plyr from 'plyr'
|
||||
import 'plyr/dist/plyr.css'
|
||||
import { makeDownload } from '~/utils/index'
|
||||
const config = useConfigStore()
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
default: () => ({}),
|
||||
}
|
||||
})
|
||||
|
||||
const emitter = defineEmits(['closeModel'])
|
||||
|
|
@ -48,12 +39,13 @@ const video = ref(null)
|
|||
const tracks = ref([])
|
||||
const sources = ref([])
|
||||
|
||||
const thumbnail = ref('')
|
||||
const thumbnail = ref('/images/placeholder.png')
|
||||
const artist = ref('')
|
||||
const title = ref('')
|
||||
const isAudio = ref(false)
|
||||
const isApple = /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent)
|
||||
const volume = useStorage('player_volume', 1)
|
||||
|
||||
let player = null;
|
||||
let hls = null;
|
||||
|
||||
const eventFunc = e => {
|
||||
|
|
@ -63,13 +55,20 @@ const eventFunc = e => {
|
|||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const isApple = /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent)
|
||||
|
||||
video.value.volume = volume.value
|
||||
|
||||
video.value.addEventListener('volumechange', () => {
|
||||
volume.value = video.value.volume
|
||||
})
|
||||
|
||||
const response = await (await request(makeDownload(config, props.item, 'api/file/info'))).json()
|
||||
|
||||
if (props.item.extras?.thumbnail) {
|
||||
thumbnail.value = '/api/thumbnail?url=' + encodePath(props.item.extras.thumbnail)
|
||||
}
|
||||
|
||||
|
||||
// -- check if mimetype is video/mp4 and device is apple
|
||||
// -- as always apple, apple like to be snowflakes.
|
||||
if (isApple) {
|
||||
|
|
@ -123,9 +122,6 @@ onMounted(async () => {
|
|||
onUpdated(() => prepareVideoPlayer())
|
||||
|
||||
onUnmounted(() => {
|
||||
if (player) {
|
||||
player.destroy()
|
||||
}
|
||||
if (hls) {
|
||||
hls.destroy()
|
||||
}
|
||||
|
|
@ -138,62 +134,23 @@ onUnmounted(() => {
|
|||
})
|
||||
|
||||
const prepareVideoPlayer = () => {
|
||||
if (false === ("mediaSession" in navigator)) {
|
||||
return
|
||||
}
|
||||
|
||||
let mediaMetadata = {
|
||||
title: title.value,
|
||||
};
|
||||
|
||||
if (thumbnail.value) {
|
||||
mediaMetadata['artwork'] = [
|
||||
{ src: thumbnail.value, sizes: '1920x1080', type: 'image/jpeg' },
|
||||
]
|
||||
mediaMetadata.artwork = [{ src: thumbnail.value, sizes: '1920x1080', type: 'image/jpeg' }]
|
||||
}
|
||||
if (artist.value) {
|
||||
mediaMetadata['artist'] = artist.value
|
||||
}
|
||||
|
||||
let opts = {
|
||||
debug: false,
|
||||
clickToPlay: true,
|
||||
keyboard: { focused: true, global: true },
|
||||
controls: [
|
||||
'play-large', 'play', 'progress', 'current-time', 'duration', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen'
|
||||
],
|
||||
fullscreen: {
|
||||
enabled: true,
|
||||
fallback: true,
|
||||
iosNative: true,
|
||||
},
|
||||
storage: {
|
||||
enabled: true,
|
||||
key: 'plyr'
|
||||
},
|
||||
artist: artist.value,
|
||||
mediaMetadata: mediaMetadata,
|
||||
captions: {
|
||||
update: true,
|
||||
},
|
||||
};
|
||||
|
||||
if (artist.value) {
|
||||
opts.artist = artist.value
|
||||
mediaMetadata.artist = artist.value
|
||||
}
|
||||
|
||||
if (title.value) {
|
||||
opts.title = title.value
|
||||
}
|
||||
|
||||
if (thumbnail.value) {
|
||||
opts.poster = thumbnail.value
|
||||
}
|
||||
|
||||
player = new Plyr(video.value, opts);
|
||||
|
||||
player.source = {
|
||||
type: isAudio.value ? 'audio' : 'video',
|
||||
title: title.value,
|
||||
poster: thumbnail.value,
|
||||
};
|
||||
|
||||
navigator.mediaSession.metadata = new MediaMetadata(mediaMetadata);
|
||||
if (title.value) {
|
||||
window.document.title = `YTPTube - Playing: ${title.value}`
|
||||
}
|
||||
|
|
@ -212,7 +169,7 @@ const attach_hls = link => {
|
|||
debug: false,
|
||||
enableWorker: true,
|
||||
lowLatencyMode: true,
|
||||
backBufferLength: 90,
|
||||
backBufferLength: 120,
|
||||
fragLoadingTimeOut: 200000,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
"moment": "^2.30.1",
|
||||
"nuxt": "^3.11.2",
|
||||
"pinia": "^2.1.7",
|
||||
"plyr": "^3.7.8",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"vue": "^3.4.21",
|
||||
"vue-router": "^4.3.0",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowImportingTsExtensions": false
|
||||
}
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowImportingTsExtensions": false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1300
ui/yarn.lock
1300
ui/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue