Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="preconnect" href="https://rsms.me/"> | |
<link rel="stylesheet" href="https://rsms.me/inter/inter.css"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/daydreamer-json/SomeFontRepo@main/somefontrepo.css"> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vidstack@^1.0.0/player/styles/default/theme.min.css"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vidstack@^1.0.0/player/styles/default/layouts/video.min.css"> | |
<script src="https://cdn.jsdelivr.net/npm/vidstack@^1.0.0/cdn/with-layouts/vidstack.js" type="module"></script> | |
<script src='https://unpkg.com/bignumber.js'></script> | |
<script src='https://unpkg.com/cbor-web'></script> | |
<style> | |
:root { font-family: 'Inter', sans-serif; } | |
@supports (font-variation-settings: normal) { | |
:root { font-family: 'Inter var', sans-serif; } | |
} | |
body { | |
margin: 0; | |
background-color: #000000; | |
width: 100vw; | |
height: 100vh; | |
font-family: 'Inter', 'Noto Sans JP', sans-serif; | |
} | |
.wrapper { | |
height: 100vh; | |
display: flex; | |
flex-direction: column; | |
} | |
#player { | |
flex-grow: 1; | |
top: 0; | |
left: 0; | |
height: 100%; | |
width: 100%; | |
font-family: 'Inter', 'Noto Sans JP', sans-serif; | |
overflow: hidden; | |
} | |
.vds-video-layout { | |
--video-font-family: 'Inter', 'Noto Sans JP', sans-serif ; | |
--video-border-radius: 0px ; | |
--video-border: 0px ; | |
} | |
:where([data-media-provider], video, media-poster) { | |
border-radius: var(--video-border-radius); | |
border: var(--video-border); | |
} | |
:where([data-media-player][data-view-type=video]:not([data-fullscreen])) { | |
border-radius: var(--video-border-radius); | |
border: var(--video-border); | |
} | |
:where([data-media-player][data-view-type=video]) { | |
border-radius: var(--video-border-radius); | |
border: var(--video-border); | |
} | |
[data-media-provider] video { | |
width: 100%; | |
height: 100%; | |
object-fit: contain; | |
} | |
media-captions { | |
/* font-family: 'SDK_JP_Web', sans-serif; */ | |
font-family: 'Inter', 'Noto Sans JP', sans-serif; | |
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.75), -1px 1px 0 rgba(0, 0, 0, 0.75), 1px -1px 0 rgba(0, 0, 0, 0.75), -1px -1px 0 rgba(0, 0, 0, 0.75); | |
} | |
footer.copyrightDisp { | |
position: fixed; | |
left: 0; | |
bottom: 0; | |
padding: 0; | |
margin: 0 0 10px 10px; | |
color: #ffffff80; | |
z-index: 2; | |
user-select: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="wrapper"> | |
<media-player | |
title="" | |
aspect-ratio="16/9" | |
crossorigin | |
id="player" | |
> | |
<media-provider id="player-media-outlet-el"> | |
</media-provider> | |
<media-audio-layout></media-audio-layout> | |
<media-video-layout></media-video-layout> | |
</media-player> | |
</div> | |
<script> | |
window.addEventListener('load', async function(){ | |
// const cbor = require('cbor-web'); | |
window.uiTranslation = { | |
"ja-JP": { | |
"Audio": "音声", | |
"Auto": "自動", | |
"Captions": "字幕", | |
"Chapters": "チャプター", | |
"Default": "既定", | |
"Mute": "ミュート", | |
"Normal": "標準", | |
"Off": "オフ", | |
"Pause": "一時停止", | |
"Play": "再生", | |
"Speed": "速度", | |
"Quality": "画質", | |
"Settings": "設定", | |
"Unmute": "ミュート解除", | |
"Seek Forward": "進む", | |
"Seek Backward": "戻る", | |
"Closed-Captions On": "字幕オン", | |
"Closed-Captions Off": "字幕オフ", | |
"Enter Fullscreen": "全画面表示", | |
"Exit Fullscreen": "全画面表示を終了", | |
"Enter PiP": "PiP", | |
"Exit PiP": "PiPを終了" | |
} | |
}; | |
// uiTranslation.cbor.ja = atob(uiTranslation.base64.ja); | |
// uiTranslation.json.ja = await cbor.decodeFirst(uiTranslation.cbor.ja); | |
document.oncontextmenu = function () {return false;} | |
window.player = document.querySelector('media-player'); | |
for (let i = 0; i < Object.keys(uiTranslation).length; i++) { | |
if (window.navigator.language == Object.keys(uiTranslation)[i]) { | |
document.querySelector('media-video-layout').translations = uiTranslation[Object.keys(uiTranslation)[i]]; | |
} | |
} | |
const pageUrlLocationHref = new URL(location.href); | |
const pageSearchParams = pageUrlLocationHref.searchParams; | |
if (pageSearchParams.has("url") === true && pageSearchParams.get("url") !== "") { | |
attachSourceToPlayer(pageSearchParams.get("url")); | |
if (pageSearchParams.has("subtitle") === true && pageSearchParams.get("subtitle") !== "") { | |
attachSubtitleSourceToPlayer(pageSearchParams.get("subtitle")); | |
} | |
} else { | |
const promptedUrl = prompt("Please input source URL"); | |
if (promptedUrl === "") { | |
alert("Source not found"); | |
} else { | |
attachSourceToPlayer(promptedUrl); | |
} | |
} | |
player.addEventListener('provider-change', (event) => { | |
const provider = event.detail; | |
if (provider?.type === 'hls') { | |
provider.library = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js'; | |
provider.config = { | |
"debug": true, | |
"enableWorker": true, | |
"lowLatencyMode": true, | |
"backBufferLength": 90 | |
}; | |
window.provider = provider; | |
} | |
}); | |
}); | |
function attachSourceToPlayer (url) { | |
player.src = url; | |
player.title = url.match(/^(?:[^:\/?#]+:)?(?:\/\/[^\/?#]*)?(?:([^?#]*\/)([^\/?#]*))?(\?[^#]*)?(?:#.*)?$/)[2].match(/^(.+?)(\.[^.]+)?$/)[1]; | |
} | |
function attachSubtitleSourceToPlayer (url) { | |
const outletElement = document.querySelector('#player-media-outlet-el'); | |
const trackElement = document.createElement("track"); | |
trackElement.src = url; | |
trackElement.kind = "subtitles"; | |
trackElement.label = "Subtitle"; | |
outletElement.appendChild(trackElement); | |
} | |
</script> | |
</body> | |
</html> |