Spaces:
Running
Running
Edit vidstack.html
Browse filesSave Volume/Mute state to localStorage
Automatically change audio language on mhy cutscene manifests
- vidstack.html +99 -27
vidstack.html
CHANGED
|
@@ -94,34 +94,40 @@
|
|
| 94 |
</media-player>
|
| 95 |
</div>
|
| 96 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
window.addEventListener('load', async function(){
|
| 98 |
// const cbor = require('cbor-web');
|
| 99 |
-
window.uiTranslation = {
|
| 100 |
-
"ja-JP": {
|
| 101 |
-
"Audio": "音声",
|
| 102 |
-
"Auto": "自動",
|
| 103 |
-
"Captions": "字幕",
|
| 104 |
-
"Chapters": "チャプター",
|
| 105 |
-
"Default": "既定",
|
| 106 |
-
"Mute": "ミュート",
|
| 107 |
-
"Normal": "標準",
|
| 108 |
-
"Off": "オフ",
|
| 109 |
-
"Pause": "一時停止",
|
| 110 |
-
"Play": "再生",
|
| 111 |
-
"Speed": "速度",
|
| 112 |
-
"Quality": "画質",
|
| 113 |
-
"Settings": "設定",
|
| 114 |
-
"Unmute": "ミュート解除",
|
| 115 |
-
"Seek Forward": "進む",
|
| 116 |
-
"Seek Backward": "戻る",
|
| 117 |
-
"Closed-Captions On": "字幕オン",
|
| 118 |
-
"Closed-Captions Off": "字幕オフ",
|
| 119 |
-
"Enter Fullscreen": "全画面表示",
|
| 120 |
-
"Exit Fullscreen": "全画面表示を終了",
|
| 121 |
-
"Enter PiP": "PiP",
|
| 122 |
-
"Exit PiP": "PiPを終了"
|
| 123 |
-
}
|
| 124 |
-
};
|
| 125 |
// uiTranslation.cbor.ja = atob(uiTranslation.base64.ja);
|
| 126 |
// uiTranslation.json.ja = await cbor.decodeFirst(uiTranslation.cbor.ja);
|
| 127 |
document.oncontextmenu = function () {return false;}
|
|
@@ -151,7 +157,7 @@
|
|
| 151 |
if (provider?.type === 'hls') {
|
| 152 |
provider.library = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js';
|
| 153 |
provider.config = {
|
| 154 |
-
"debug":
|
| 155 |
"enableWorker": true,
|
| 156 |
"lowLatencyMode": true,
|
| 157 |
"backBufferLength": 90
|
|
@@ -159,6 +165,14 @@
|
|
| 159 |
window.provider = provider;
|
| 160 |
}
|
| 161 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
});
|
| 163 |
function attachSourceToPlayer (url) {
|
| 164 |
player.src = url;
|
|
@@ -172,6 +186,64 @@
|
|
| 172 |
trackElement.label = "Subtitle";
|
| 173 |
outletElement.appendChild(trackElement);
|
| 174 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
</script>
|
| 176 |
</body>
|
| 177 |
</html>
|
|
|
|
| 94 |
</media-player>
|
| 95 |
</div>
|
| 96 |
<script>
|
| 97 |
+
const uiTranslation = {
|
| 98 |
+
"ja-JP": {
|
| 99 |
+
"Audio": "音声",
|
| 100 |
+
"Auto": "自動",
|
| 101 |
+
"Captions": "字幕",
|
| 102 |
+
"Chapters": "チャプター",
|
| 103 |
+
"Default": "既定",
|
| 104 |
+
"Mute": "ミュート",
|
| 105 |
+
"Normal": "標準",
|
| 106 |
+
"Off": "オフ",
|
| 107 |
+
"Pause": "一時停止",
|
| 108 |
+
"Play": "再生",
|
| 109 |
+
"Speed": "速度",
|
| 110 |
+
"Quality": "画質",
|
| 111 |
+
"Settings": "設定",
|
| 112 |
+
"Unmute": "ミュート解除",
|
| 113 |
+
"Seek Forward": "進む",
|
| 114 |
+
"Seek Backward": "戻る",
|
| 115 |
+
"Closed-Captions On": "字幕オン",
|
| 116 |
+
"Closed-Captions Off": "字幕オフ",
|
| 117 |
+
"Enter Fullscreen": "全画面表示",
|
| 118 |
+
"Exit Fullscreen": "全画面表示を終了",
|
| 119 |
+
"Enter PiP": "PiP",
|
| 120 |
+
"Exit PiP": "PiPを終了"
|
| 121 |
+
}
|
| 122 |
+
};
|
| 123 |
+
const pageUUID = "d511b8f7-5579-41a6-8450-e9f958507f94";
|
| 124 |
+
let playerConfigObject = {
|
| 125 |
+
"volume": null,
|
| 126 |
+
"muted": null
|
| 127 |
+
};
|
| 128 |
+
window.volumeChangeEventCounter = 0;
|
| 129 |
window.addEventListener('load', async function(){
|
| 130 |
// const cbor = require('cbor-web');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
// uiTranslation.cbor.ja = atob(uiTranslation.base64.ja);
|
| 132 |
// uiTranslation.json.ja = await cbor.decodeFirst(uiTranslation.cbor.ja);
|
| 133 |
document.oncontextmenu = function () {return false;}
|
|
|
|
| 157 |
if (provider?.type === 'hls') {
|
| 158 |
provider.library = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js';
|
| 159 |
provider.config = {
|
| 160 |
+
"debug": false,
|
| 161 |
"enableWorker": true,
|
| 162 |
"lowLatencyMode": true,
|
| 163 |
"backBufferLength": 90
|
|
|
|
| 165 |
window.provider = provider;
|
| 166 |
}
|
| 167 |
});
|
| 168 |
+
importConfigFromBrowser();
|
| 169 |
+
player.addEventListener('volume-change', (event) => {
|
| 170 |
+
volumeChangeSaveToConfig();
|
| 171 |
+
});
|
| 172 |
+
const { audioTracks } = player.state;
|
| 173 |
+
player.subscribe(({ audioTracks }) => {
|
| 174 |
+
mhyLangAutoSelect(JSON.stringify(audioTracks, '', ' '));
|
| 175 |
+
});
|
| 176 |
});
|
| 177 |
function attachSourceToPlayer (url) {
|
| 178 |
player.src = url;
|
|
|
|
| 186 |
trackElement.label = "Subtitle";
|
| 187 |
outletElement.appendChild(trackElement);
|
| 188 |
}
|
| 189 |
+
function volumeChangeSaveToConfig () {
|
| 190 |
+
if (volumeChangeEventCounter >= 0) {
|
| 191 |
+
playerConfigObject.volume = player.volume;
|
| 192 |
+
playerConfigObject.muted = player.muted;
|
| 193 |
+
saveConfigToBrowser();
|
| 194 |
+
}
|
| 195 |
+
volumeChangeEventCounter += 1;
|
| 196 |
+
}
|
| 197 |
+
function importConfigFromBrowser () {
|
| 198 |
+
if (window.localStorage && localStorage.getItem(`${pageUUID}`) !== null) {
|
| 199 |
+
playerConfigObject = JSON.parse(localStorage.getItem(`${pageUUID}`));
|
| 200 |
+
player.volume = playerConfigObject.volume;
|
| 201 |
+
player.muted = playerConfigObject.muted;
|
| 202 |
+
console.warn(`Loaded config from localStorage\n${pageUUID} = ${JSON.stringify(playerConfigObject, '', ' ')}`);
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
function saveConfigToBrowser () {
|
| 206 |
+
if (window.localStorage) {
|
| 207 |
+
localStorage.setItem(`${pageUUID}`, JSON.stringify(playerConfigObject));
|
| 208 |
+
console.warn(`Saved config to localStorage\n${pageUUID} = ${JSON.stringify(playerConfigObject, '', ' ')}`);
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
function mhyLangAutoSelect (audioTracks) {
|
| 212 |
+
const testBefore = [
|
| 213 |
+
{
|
| 214 |
+
"id": "0",
|
| 215 |
+
"label": "Chinese",
|
| 216 |
+
"language": "zh-CN",
|
| 217 |
+
"kind": "main"
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"id": "1",
|
| 221 |
+
"label": "English",
|
| 222 |
+
"language": "en-US",
|
| 223 |
+
"kind": "main"
|
| 224 |
+
},
|
| 225 |
+
{
|
| 226 |
+
"id": "2",
|
| 227 |
+
"label": "Japanese",
|
| 228 |
+
"language": "ja-JP",
|
| 229 |
+
"kind": "main"
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"id": "3",
|
| 233 |
+
"label": "Korean",
|
| 234 |
+
"language": "ko-KR",
|
| 235 |
+
"kind": "main"
|
| 236 |
+
}
|
| 237 |
+
];
|
| 238 |
+
if (audioTracks === JSON.stringify(testBefore, '', ' ')) {
|
| 239 |
+
for (let i = 0; i < testBefore.length; i++) {
|
| 240 |
+
if (window.navigator.language.slice(0,2) === testBefore[i].language.slice(0,2)) {
|
| 241 |
+
player.audioTracks[i].selected = true;
|
| 242 |
+
console.warn(`Player audio language has been automatically changed to\n${JSON.stringify(player.audioTracks[i], '', ' ')}`);
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
}
|
| 247 |
</script>
|
| 248 |
</body>
|
| 249 |
</html>
|