Added plyr as video player.

This commit is contained in:
ArabCoders 2023-12-16 17:58:48 +03:00
parent f0eb924185
commit bed10cabf4
4 changed files with 71 additions and 32 deletions

View file

@ -16,6 +16,7 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"hls.js": "^1.4.12", "hls.js": "^1.4.12",
"moment": "^2.29.4", "moment": "^2.29.4",
"plyr": "^3.7.8",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"vue": "^3.3.9", "vue": "^3.3.9",
"vue-toastification": "^2.0.0-rc.5" "vue-toastification": "^2.0.0-rc.5"
@ -4967,6 +4968,11 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
}, },
"node_modules/custom-event-polyfill": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz",
"integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="
},
"node_modules/debounce": { "node_modules/debounce": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@ -7512,6 +7518,11 @@
"json5": "lib/cli.js" "json5": "lib/cli.js"
} }
}, },
"node_modules/loadjs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/loadjs/-/loadjs-4.2.0.tgz",
"integrity": "sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA=="
},
"node_modules/locate-path": { "node_modules/locate-path": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -8746,6 +8757,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/plyr": {
"version": "3.7.8",
"resolved": "https://registry.npmjs.org/plyr/-/plyr-3.7.8.tgz",
"integrity": "sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==",
"dependencies": {
"core-js": "^3.26.1",
"custom-event-polyfill": "^1.0.7",
"loadjs": "^4.2.0",
"rangetouch": "^2.0.1",
"url-polyfill": "^1.1.12"
}
},
"node_modules/portfinder": { "node_modules/portfinder": {
"version": "1.0.32", "version": "1.0.32",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
@ -9501,6 +9524,11 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/rangetouch": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.1.tgz",
"integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA=="
},
"node_modules/raw-body": { "node_modules/raw-body": {
"version": "2.5.1", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
@ -10907,6 +10935,11 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url-polyfill": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz",
"integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A=="
},
"node_modules/util-deprecate": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View file

@ -17,6 +17,7 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"hls.js": "^1.4.12", "hls.js": "^1.4.12",
"moment": "^2.29.4", "moment": "^2.29.4",
"plyr": "^3.7.8",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"vue": "^3.3.9", "vue": "^3.3.9",
"vue-toastification": "^2.0.0-rc.5" "vue-toastification": "^2.0.0-rc.5"

View file

@ -8,7 +8,7 @@
<div class="modal is-active" v-if="video_link"> <div class="modal is-active" v-if="video_link">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content" style="width:auto;">
<VideoPlayer type="default" :link="video_link" :isMuted="false" autoplay="true" :isControls="true" <VideoPlayer type="default" :link="video_link" :isMuted="false" autoplay="true" :isControls="true"
class="is-fullwidth" /> class="is-fullwidth" />
</div> </div>

View file

@ -1,13 +1,14 @@
<template> <template>
<video @pause="pause" @ended="pause" @keyup="changeSpeed" ref="video" :poster="previewImageLink" :controls="isControls" <video ref="video" :poster="previewImageLink" :controls="isControls" :title="title">
:title="title">
<source :src="link" type="application/x-mpegURL" /> <source :src="link" type="application/x-mpegURL" />
</video> </video>
</template> </template>
<script setup> <script setup>
import { onMounted, onUpdated, ref, defineProps, defineEmits } from 'vue' import { onMounted, onUpdated, ref, defineProps, onUnmounted } from 'vue'
import Hls from 'hls.js' import Hls from 'hls.js'
import Plyr from 'plyr'
import 'plyr/dist/plyr.css'
const props = defineProps({ const props = defineProps({
previewImageLink: { previewImageLink: {
@ -18,26 +19,19 @@ const props = defineProps({
type: String, type: String,
default: '' default: ''
}, },
progress: {
type: Number,
default: 0
},
title: { title: {
type: String, type: String,
default: '' default: ''
}, },
isMuted: {
type: Boolean,
default: false
},
isControls: { isControls: {
type: Boolean, type: Boolean,
default: true default: true
}, },
}) })
const emit = defineEmits(['pause', 'test'])
const video = ref(null) const video = ref(null)
const player = ref(null)
const hls = ref(null)
onMounted(() => { onMounted(() => {
prepareVideoPlayer() prepareVideoPlayer()
@ -47,35 +41,46 @@ onUpdated(() => {
prepareVideoPlayer() prepareVideoPlayer()
}) })
onUnmounted(() => {
player.value.destroy()
hls.value.destroy()
})
const prepareVideoPlayer = () => { const prepareVideoPlayer = () => {
let hls = new Hls({ player.value = new Plyr(video.value, {
clickToPlay: true,
keyboard: { focused: true, global: true },
controls: [
'play-large', 'play', 'progress', 'current-time', 'duration', 'mute', 'volume', 'pip', 'airplay', 'fullscreen'
],
fullscreen: {
enabled: true,
fallback: true,
iosNative: true,
},
storage: {
enabled: true,
key: 'plyr_volume'
},
mediaMetadata: {
title: props.title.value
}
});
hls.value = new Hls({
debug: false, debug: false,
enableWorker: true, enableWorker: true,
lowLatencyMode: true, lowLatencyMode: true,
backBufferLength: 90, backBufferLength: 90,
}); });
hls.loadSource(props.link) hls.value.loadSource(props.link)
if (video.value) { if (video.value) {
hls.attachMedia(video.value) hls.value.attachMedia(video.value)
video.value.muted = props.isMuted
video.value.currentTime = props.progress
}
}
const pause = () => {
const currentTime = video?.value?.currentTime || 0
emit('pause', currentTime)
}
const changeSpeed = (e) => {
if (e.key === 'w' && video.value) {
video.value.playbackRate = video.value.playbackRate + 0.25
} else if (e.key === 's' && video.value) {
video.value.playbackRate = video.value.playbackRate - 0.25
} }
} }
</script> </script>
<style></style>