103 lines
2.6 KiB
Vue
103 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import Artplayer from "artplayer";
|
|
import Hls from "hls.js";
|
|
import { createVueControlSmart } from "~/components/util/player-control";
|
|
import { EpisodeChangeType } from "./ChangeEpisodeButton.vue";
|
|
import { UiPlayerChangeEpisodeButton } from "#components";
|
|
|
|
interface Props {
|
|
urls: any;
|
|
id: string;
|
|
episodeButton: boolean;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
});
|
|
|
|
const emit = defineEmits(['get-instance'])
|
|
|
|
const options = computed(() => {
|
|
const controls = []
|
|
if (props.episodeButton) {
|
|
controls.push(
|
|
createVueControlSmart(UiPlayerChangeEpisodeButton, {
|
|
name: "next-episode",
|
|
index: 50,
|
|
tooltip: "Next episode",
|
|
type: EpisodeChangeType.NEXT
|
|
}, {
|
|
click: () => console.log("NEXT")
|
|
})
|
|
)
|
|
controls.push(
|
|
createVueControlSmart(UiPlayerChangeEpisodeButton, {
|
|
name: "previous-episode",
|
|
index: 50,
|
|
tooltip: "Previous episode",
|
|
type: EpisodeChangeType.PREVIOUS
|
|
}, {
|
|
click: () => console.log("Previous")
|
|
})
|
|
)
|
|
}
|
|
return {
|
|
url: props.urls[0].url || '',
|
|
type: 'm3u8',
|
|
customType: {
|
|
m3u8: playM3u8,
|
|
},
|
|
quality: props.urls,
|
|
autoSize: true,
|
|
autoMini: true,
|
|
playbackRate: true,
|
|
fullscreen: true,
|
|
aspectRatio: true,
|
|
setting: true,
|
|
lock: true,
|
|
autoOrientation: true,
|
|
autoPlayback: true,
|
|
id: props.id,
|
|
controls: controls,
|
|
}
|
|
})
|
|
const artplayerRef = ref();
|
|
const instance = ref();
|
|
|
|
function playM3u8(video: HTMLMediaElement, url: string, art: Artplayer) {
|
|
if (Hls.isSupported()) {
|
|
if (art.hls) art.hls.destroy();
|
|
const hls = new Hls();
|
|
hls.loadSource(url);
|
|
hls.attachMedia(video);
|
|
art.hls = hls;
|
|
art.on('destroy', () => hls.destroy());
|
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
video.src = url;
|
|
} else {
|
|
art.notice.show = 'Unsupported playback format: m3u8';
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
instance.value = new Artplayer({
|
|
container: artplayerRef.value,
|
|
...options.value,
|
|
})
|
|
nextTick(() => {
|
|
emit('get-instance')
|
|
})
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
if (instance.value && instance.value.destroy) {
|
|
instance.value.destroy(false)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex items-center justify-center">
|
|
<div class="w-2/3 aspect-video" ref="artplayerRef"></div>
|
|
</div>
|
|
</template>
|