@kolbo/mcp 1.110.0 → 1.110.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/apps/html.js +40 -0
- package/src/apps/theme.js +11 -0
package/package.json
CHANGED
package/src/apps/html.js
CHANGED
|
@@ -236,9 +236,13 @@ function showPeekItem(time) {
|
|
|
236
236
|
var it = peekList[peekIndex];
|
|
237
237
|
var img = el('peek-img');
|
|
238
238
|
var vid = el('peek-video');
|
|
239
|
+
var oldNote = el('peek-stage') && el('peek-stage').querySelector('.k-vnote');
|
|
240
|
+
if (oldNote) oldNote.parentNode.removeChild(oldNote);
|
|
241
|
+
vid.removeAttribute('data-unplayable');
|
|
239
242
|
if (it.kind === 'video') {
|
|
240
243
|
img.removeAttribute('src');
|
|
241
244
|
vid.setAttribute('src', it.url);
|
|
245
|
+
guardPlayback(vid);
|
|
242
246
|
if (time) vid.addEventListener('loadedmetadata', function () { try { vid.currentTime = time; } catch (e) {} }, { once: true });
|
|
243
247
|
var p = vid.play && vid.play();
|
|
244
248
|
if (p && p.catch) p.catch(function () {});
|
|
@@ -363,6 +367,42 @@ function wireVideoExpand(root) {
|
|
|
363
367
|
b.addEventListener('keydown', mark);
|
|
364
368
|
v.addEventListener('dblclick', function (e) { e.preventDefault(); mark(); b.click(); });
|
|
365
369
|
v.parentNode.insertBefore(b, v.nextSibling);
|
|
370
|
+
guardPlayback(v);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
// Some outputs cannot be decoded by a browser: 10/12-bit HEVC (Bytedance
|
|
374
|
+
// Upscaler Pro, Seedance 1080p masters) either errors or plays sound over a
|
|
375
|
+
// black frame. Detect both and replace the dead player with a clear note and
|
|
376
|
+
// a Download button instead of leaving the user staring at nothing.
|
|
377
|
+
function guardPlayback(v) {
|
|
378
|
+
if (!v || v.getAttribute('data-guard')) return;
|
|
379
|
+
v.setAttribute('data-guard', '1');
|
|
380
|
+
function fail() {
|
|
381
|
+
if (v.getAttribute('data-unplayable') || !v.parentNode) return;
|
|
382
|
+
v.setAttribute('data-unplayable', '1');
|
|
383
|
+
try { v.pause(); } catch (e) {}
|
|
384
|
+
var url = v.currentSrc || v.getAttribute('src');
|
|
385
|
+
var note = document.createElement('div');
|
|
386
|
+
note.className = 'k-vnote';
|
|
387
|
+
note.innerHTML = '<div class="k-vnote-t"></div><div class="k-vnote-s"></div><button type="button" class="k-btn primary"></button>';
|
|
388
|
+
note.querySelector('.k-vnote-t').textContent = "This video can't play in the browser";
|
|
389
|
+
note.querySelector('.k-vnote-s').textContent = 'It uses a high-quality format (HEVC, 10/12-bit) most browsers do not decode. Download it and open it in a video player.';
|
|
390
|
+
var dl = note.querySelector('button');
|
|
391
|
+
dl.innerHTML = ICONS.download + ' Download video';
|
|
392
|
+
dl.onclick = function (e) { e.stopPropagation(); window.kolbo.openLink(downloadUrl(url)); };
|
|
393
|
+
v.parentNode.insertBefore(note, v.nextSibling);
|
|
394
|
+
if (window.kolbo && window.kolbo.notifySize) window.kolbo.notifySize();
|
|
395
|
+
}
|
|
396
|
+
v.addEventListener('error', function () {
|
|
397
|
+
var code = v.error && v.error.code;
|
|
398
|
+
// 3 = decode failure, 4 = format not supported. Network errors (2) are not a format problem.
|
|
399
|
+
if (code === 3 || code === 4) fail();
|
|
400
|
+
});
|
|
401
|
+
// Sound with no picture: time advances but no video frame was ever decoded.
|
|
402
|
+
v.addEventListener('timeupdate', function () {
|
|
403
|
+
if (v.currentTime < 1.2 || v.getAttribute('data-unplayable')) return;
|
|
404
|
+
var q = v.getVideoPlaybackQuality ? v.getVideoPlaybackQuality() : null;
|
|
405
|
+
if ((q && q.totalVideoFrames === 0) || (v.readyState >= 2 && v.videoWidth === 0)) fail();
|
|
366
406
|
});
|
|
367
407
|
}
|
|
368
408
|
if (window.MutationObserver) {
|
package/src/apps/theme.js
CHANGED
|
@@ -222,6 +222,17 @@ html.k-peek-fs .k-card { min-height: 0; backdrop-filter: none; -webkit-backdrop-
|
|
|
222
222
|
display: inline-flex; align-items: center; justify-content: center;
|
|
223
223
|
}
|
|
224
224
|
.k-vexpand:hover { background: var(--brand); border-color: var(--brand); }
|
|
225
|
+
/* Undecodable video (10/12-bit HEVC): the dead player is replaced by a note. */
|
|
226
|
+
video[data-unplayable] { display: none !important; }
|
|
227
|
+
video[data-unplayable] ~ .k-vexpand { display: none; }
|
|
228
|
+
.k-vnote { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
|
|
229
|
+
width: 100%; min-height: 160px; padding: 18px 16px; border-radius: 10px; text-align: center;
|
|
230
|
+
background: rgba(255, 255, 255, 0.05); }
|
|
231
|
+
.k-vnote-t { font-size: 13px; font-weight: 600; color: var(--text); }
|
|
232
|
+
.k-vnote-s { font-size: 12px; color: var(--text-muted); max-width: 360px; margin-bottom: 4px; }
|
|
233
|
+
.k-peek-stage .k-vnote { max-width: 440px; color: #fff; }
|
|
234
|
+
.k-peek-stage .k-vnote-t { color: #fff; }
|
|
235
|
+
.k-peek-stage .k-vnote-s { color: rgba(255, 255, 255, 0.7); }
|
|
225
236
|
/* Recent Chromium still draws the native button despite controlslist. */
|
|
226
237
|
video::-webkit-media-controls-fullscreen-button { display: none !important; }
|
|
227
238
|
/* ---- Plans / upgrade card ---- */
|