Skip to content

Commit

Permalink
Update videoplayer
Browse files Browse the repository at this point in the history
  • Loading branch information
sinnedpenguin committed Nov 11, 2023
1 parent 62bff2a commit cda1e72
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 76 deletions.
168 changes: 105 additions & 63 deletions src/lib/components/videoplayer.svelte
Original file line number Diff line number Diff line change
@@ -1,81 +1,123 @@
<script lang="ts">
import Player from '@oplayer/core'
import ui from '@oplayer/ui'
import OHls from '@oplayer/hls'
import { onDestroy, onMount } from 'svelte';
import Artplayer from 'artplayer';
import Hls from 'hls.js';
import { options } from '$lib/config/videoplayer';
import type { Quality, Subtitle } from '$lib/types/videoplayer';
import '../../styles/videoplayer.css';
import { uiOptions } from '$lib/config/videoplayer';
export let url = '';
let player: Player;
let subtitles: Subtitle[];
onMount(async() => {
const res = await fetch(url);
const data = await res.json();
const { sources } = data;
const videoUrl = sources[0].url;
let art: Artplayer & { hls?: Hls } | undefined;
let videoUrl = '';
let qualityOptions: Quality[] = [];
let subtitles: Subtitle[] = [];
let selectedSubtitle: Subtitle | undefined;
async function fetchVideoData() {
const response = await fetch(url);
const data = await response.json();
qualityOptions = data.sources;
subtitles = data.subtitles;
player = Player.make('#oplayer', {
source: {
src: videoUrl,
},
autoplay: true,
})
.use([ui({
...uiOptions,
subtitle: {
background: true,
source: subtitles.map((subtitle) => ({
name: subtitle.lang,
src: subtitle.url,
})),
const autoQualityOption = qualityOptions.find((qualityOption) => qualityOption.quality === 'auto');
videoUrl = autoQualityOption ? autoQualityOption.url : data.sources[0].url;
}
function setupHlsPlayer(video: HTMLMediaElement, url: string, art: Artplayer & { hls?: Hls }) {
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';
}
}
function initializeArtplayer() {
const defaultSubtitle = subtitles.find((subtitle) => subtitle.lang.toLowerCase().startsWith('eng'));
art = new Artplayer({
...options,
container: '.artplayer-app',
url: videoUrl,
type: 'm3u8',
customType: {
m3u8: setupHlsPlayer,
},
settings: [{
name: 'Quality',
icon: '',
type: 'selector',
key: 'quality',
children: sources.map((source: Quality) => ({
name: source.quality,
value: source.url,
default: source.quality === 'auto',
})),
onChange({value}) {
player.changeQuality({src: value});
}
}]
})])
.use([OHls()])
.create();
settings: [
{
html: 'Quality',
icon: `<svg viewBox="0 0 24 24" fill="currentColor" className='w-7 h-7'><path d="M14.5 13.5h2v-3h-2M18 14a1 1 0 01-1 1h-.75v1.5h-1.5V15H14a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1m-7 5H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11m8-5H5c-1.11 0-2 .89-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2z" />
</svg>`,
selector: qualityOptions.map((qualityOption) => ({
default: qualityOption.quality === 'auto',
html: qualityOption.quality,
url: qualityOption.url,
})),
onSelect: (item) => {
const qualityOption = qualityOptions.find((q) => q.quality === item.html);
if (qualityOption) {
art?.switchQuality(item.url);
if (selectedSubtitle) {
art?.subtitle.switch(selectedSubtitle.url);
}
return item.html;
}
},
},
{
html: 'Subtitle',
icon: `<svg viewBox="0 0 1024 1024" version="1.1"><path d="M800 170.666667A138.666667 138.666667 0 0 1 938.666667 309.333333v405.546667a138.666667 138.666667 0 0 1-138.666667 138.666667H224A138.666667 138.666667 0 0 1 85.333333 714.88V309.333333a138.666667 138.666667 0 0 1 130.816-138.453333L224 170.666667h576z m0 64H224l-6.144 0.256A74.666667 74.666667 0 0 0 149.333333 309.333333v405.546667c0 41.216 33.450667 74.666667 74.666667 74.666667h576a74.666667 74.666667 0 0 0 74.666667-74.666667V309.333333a74.666667 74.666667 0 0 0-74.666667-74.666666zM234.666667 512c0-134.229333 115.754667-203.733333 218.538666-145.109333A32 32 0 0 1 421.461333 422.4C361.856 388.437333 298.666667 426.410667 298.666667 512c0 85.546667 63.317333 123.562667 122.88 89.728a32 32 0 0 1 31.573333 55.637333C350.549333 715.733333 234.666667 646.101333 234.666667 512z m320 0c0-134.229333 115.754667-203.733333 218.538666-145.109333a32 32 0 0 1-31.744 55.552C681.856 388.437333 618.666667 426.410667 618.666667 512c0 85.546667 63.317333 123.562667 122.88 89.728a32 32 0 0 1 31.573333 55.637333C670.549333 715.733333 554.666667 646.101333 554.666667 512z"></path></svg>`,
selector: subtitles.map((subtitle) => ({
default: subtitle.lang.toLowerCase().startsWith('eng'),
html: subtitle.lang,
url: subtitle.url,
})),
onSelect: (item) => {
const subtitle = subtitles.find((s) => s.lang === item.html);
if (subtitle) {
art?.subtitle.switch(item.url);
return item.html;
}
},
},
],
});
const forward = document.createElement("button");
forward.className = "forward";
forward.innerHTML =
'<svg viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.444 3.685A10 10 0 0 1 18 4h-2v2h4a1 1 0 0 0 1-1V1h-2v1.253A12 12 0 1 0 24 12h-2A10 10 0 1 1 6.444 3.685ZM22 4v3h-3v2h4a1 1 0 0 0 1-1V4h-2Zm-9.398 11.576c.437.283.945.424 1.523.424s1.083-.141 1.513-.424c.437-.29.774-.694 1.009-1.215.235-.527.353-1.148.353-1.861 0-.707-.118-1.324-.353-1.851-.235-.527-.572-.932-1.009-1.215-.43-.29-.935-.434-1.513-.434-.578 0-1.086.145-1.523.434-.43.283-.764.688-.999 1.215-.235.527-.353 1.144-.353 1.851 0 .713.118 1.334.353 1.86.236.522.568.927.999 1.216Zm2.441-1.485c-.222.373-.528.56-.918.56s-.696-.187-.918-.56c-.222-.38-.333-.91-.333-1.591 0-.681.111-1.208.333-1.581.222-.38.528-.57.918-.57s.696.19.918.57c.222.373.333.9.333 1.581 0 .681-.111 1.212-.333 1.59Zm-6.439-3.375v5.14h1.594V9.018L7 9.82v1.321l1.604-.424Z" fill="currentColor"></path></svg>';
forward.onclick = function () {
player.seek(player.currentTime + 10);
};
if (defaultSubtitle) {
art.subtitle.switch(defaultSubtitle.url);
selectedSubtitle = defaultSubtitle;
}
const backward = document.createElement("button");
backward.className = "backward";
backward.innerHTML =
'<svg viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.02 2.048A10 10 0 1 1 2 12H0a12 12 0 1 0 5-9.747V1H3v4a1 1 0 0 0 1 1h4V4H6a10 10 0 0 1 5.02-1.952ZM2 4v3h3v2H1a1 1 0 0 1-1-1V4h2Zm12.125 12c-.578 0-1.086-.141-1.523-.424-.43-.29-.764-.694-.999-1.215-.235-.527-.353-1.148-.353-1.861 0-.707.118-1.324.353-1.851.236-.527.568-.932.999-1.215.437-.29.945-.434 1.523-.434s1.083.145 1.513.434c.437.283.774.688 1.009 1.215.235.527.353 1.144.353 1.851 0 .713-.118 1.334-.353 1.86-.235.522-.572.927-1.009 1.216-.43.283-.935.424-1.513.424Zm0-1.35c.39 0 .696-.186.918-.56.222-.378.333-.909.333-1.59s-.111-1.208-.333-1.581c-.222-.38-.528-.57-.918-.57s-.696.19-.918.57c-.222.373-.333.9-.333 1.581 0 .681.111 1.212.333 1.59.222.374.528.56.918.56Zm-5.521 1.205v-5.139L7 11.141V9.82l3.198-.8v6.835H8.604Z" fill="currentColor"></path></svg>';
backward.onclick = function () {
player.seek(player.currentTime - 10);
};
art.on('subtitleUpdate', (text: string) => {
if (art && art.template.$subtitle) {
art.template.$subtitle.style.fontSize = '1.2em';
art.template.$subtitle.innerHTML = text
.replaceAll('<p>', '')
.replaceAll('</p>', ' ')
.replaceAll('&lt;i&gt;', '<i>')
.replaceAll('&lt;/i&gt;', '</i>')
.replaceAll('&lt;b&gt;', '<b>')
.replaceAll('&lt;/b&gt;', '</b>');
}
});
}
player.$root.appendChild(backward);
player.$root.appendChild(forward);
onMount(async () => {
await fetchVideoData();
initializeArtplayer();
});
onDestroy(() => {
if (player) {
player.destroy();
if (art) {
art.destroy(false);
}
});
</script>

<div id="oplayer"class="h-60 sm:h-auto md:h-[50vh] lg:h-[60vh] xl:h-[70vh]"/>
<div class="artplayer-app h-60 sm:h-auto md:h-[50vh] lg:h-[60vh] xl:h-[70vh]" />
29 changes: 21 additions & 8 deletions src/lib/config/videoplayer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
export const uiOptions = {
export const options = {
container: '.artplayer-app',
volume: 0.5,
hotkey: true,
isLive: false,
muted: false,
autoplay: false,
pip: true,
autoOrientation: true,
setting: true,
playbackRate: true,
aspectRatio: true,
fullscreen: true,
coverButton: true,
miniProgressBar: true,
forceLandscapeOnFullscreen: true,
screenshot: false,
pictureInPicture: true,
theme: {
primaryColor: "rgb(250,204,21)"
},
mutex: true,
backdrop: true,
playsInline: true,
autoPlayback: true,
airplay: true,
theme: '#FACC15',
moreVideoAttr: {
crossOrigin: 'anonymous',
}
}
Binary file removed static/favicon2.ico
Binary file not shown.
5 changes: 0 additions & 5 deletions static/logo.svg

This file was deleted.

0 comments on commit cda1e72

Please sign in to comment.