Skip to content

Commit

Permalink
[VMediaPlayer] Create VMediaPlayer component for video streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
m4heshd committed May 20, 2024
1 parent 578ccac commit b4f0120
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
127 changes: 127 additions & 0 deletions frontend/src/components/VMediaPlayer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<template>
<div class="v-media-player">
<video
ref="video"
:data-poster="vPoster"
controls
crossorigin
playsinline
>
</video>
</div>
</template>

<script setup>
// Core
import {nextTick, onBeforeUnmount, onMounted, ref} from 'vue';
// Modules
import Plyr from 'plyr';
import Hls from 'hls.js';
// Props
const props = defineProps({
vPoster: String,
vSource: String,
});
// Template refs
const video = ref(null);
// Video player setup
let player = null;
let hls = null;
function onQualityChange(quality) {
if (quality === 0) {
hls.currentLevel = -1;
} else {
hls.levels.forEach((level, levelIndex) => {
if (level.height === quality) {
hls.currentLevel = levelIndex;
}
});
}
}
function initPlayer(resolutions) {
player = new Plyr(video.value, {
captions: {
active: false,
update: true,
language: 'en'
},
quality: {
default: 0,
options: resolutions,
forced: true,
onChange: (quality) => onQualityChange(quality)
},
i18n: {
qualityLabel: {
0: 'Auto'
}
},
keyboard: {
global: true
}
});
player.on('languagechange', () => {
setTimeout(() => hls.subtitleTrack = player.currentTrack, 50);
});
hls.attachMedia(video.value);
}
function playSource(source) {
if (!Hls.isSupported()) {
video.src = source;
} else {
hls = new Hls();
hls.loadSource(source);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
const resolutions = hls.levels.map((l) => l.height);
resolutions.unshift(0);
initPlayer(resolutions);
});
}
}
// Lifecycle hooks
onMounted(() =>
nextTick(() =>
playSource(props.vSource)
)
);
onBeforeUnmount(() => {
player.destroy(() => {
hls.destroy();
}, false);
});
</script>

<style lang="scss">
.v-media-player {
min-width: 100%;
--plyr-color-main: var(--primary);
video {
min-width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
* {
all: revert;
&:after {
all: revert;
}
}
}
@import "plyr/dist/plyr";
</style>
49 changes: 49 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
},
"dependencies": {
"beercss": "2.2.11",
"hls.js": "1.5.8",
"material-dynamic-colors": "0.0.10",
"pinia": "2.1.7",
"plyr": "3.7.8",
"socket.io-client": "4.5.2",
"vue": "3.4.15",
"vue-toastification": "2.0.0-rc.5"
Expand Down

0 comments on commit b4f0120

Please sign in to comment.