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>
|