-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
62bff2a
commit cda1e72
Showing
4 changed files
with
126 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('<i>', '<i>') | ||
.replaceAll('</i>', '</i>') | ||
.replaceAll('<b>', '<b>') | ||
.replaceAll('</b>', '</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]" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 not shown.
This file was deleted.
Oops, something went wrong.