mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-16 17:46:17 -08:00
* feat: support batch video upscaling with folder upload and directory save - Add multi-file selection and entire folder upload (webkitdirectory) - Support drag & drop of both files and folders via FileSystemEntry API - Add save directory picker using File System Access API (showDirectoryPicker) - Process videos sequentially with per-file progress and status tracking - Add right-side result list with click-to-compare functionality - Add per-video duration and total batch duration display - Add retry button for failed items with error detail display - Remove auto-play on comparison viewer load - Fix worker error handling: handle "error" command to reject stale promises - Fix event listener accumulation in video comparison (AbortController) - Fix XSS risk by escaping HTML in all innerHTML injections - Fix URL revocation timing in download to prevent large file truncation - Extract writeToSaveDirectory and truncateName helpers to reduce duplication - Add Usage Guide panel explaining single/multiple/folder upload options Files changed: docs/upscaler/index.html (+1110/-181) docs/upscaler/upscaler.js (+110) * fix: prevent auto-play and resource consumption during upscaling - Set preload="metadata" on preview and comparison video elements - Explicitly pause preview video after setting src in showVideoPreview - Remove preview video seek sync from batch processing progress callbacks (was causing continuous decode during upscaling, wasting GPU resources) - Remove preview video seek sync from retry progress callback - All videos now require manual play; no background resource usage * fix: improve upscaled video quality with higher bitrate and codec support - Raise base bitrate from 2.5 Mbps (25e5) to 8 Mbps (8e6) for standard and firefox processors, preventing quality loss when source videos have high bitrates (e.g. 720p @ 16.7 Mbps was producing 1440p @ 10 Mbps, smaller than the original file) - Double the bitrate for mediabunny processor (X.n1 * 2) to account for the 4x pixel increase from 2x upscaling - Add H.264 Level 5.1 (avc1.640033) and Level 5.2 (avc1.640034) codecs to the fallback lists, since Level 4.0 (avc1.640028, ~24.6 Mbps) cannot support the higher bitrates for 1440p+ outputs - Add latencyMode: "quality" to VideoEncoder configs for both standard and firefox processors, prioritizing encoding quality over latency (suitable for offline processing) * feat: add video data comparison panel for original vs upscaled metrics - Add a comparison data table below the file info bar showing 6 metrics: Resolution, File Size, Duration, Est. Bitrate, Pixels, Process Time - Display per-metric change percentage with color-coded indicators: green (↑) for improvements, red (↓) for regressions, gray for neutral - Estimated bitrate calculated from file size × 8 / video duration - Table renders after both original and upscaled video metadata loads - Auto-hide panel on reset * fix: make video data comparison panel full-width and responsive - Move comparison data table from inside the left column to the full-width area below the left/right layout, so it is no longer constrained by the comparison viewer column width - Remove table-fixed colgroup and overflow-x-auto that caused horizontal scrolling on smaller screens - Table now uses w-full auto-layout, displaying all 4 columns (Metric, Original, Upscaled, Change) without requiring horizontal scrolling --------- Co-authored-by: rionzhao <rionzhao@tencent.com>
8 lines
4.4 KiB
JavaScript
8 lines
4.4 KiB
JavaScript
/*!
|
|
* artplayer-plugin-chromecast.js v1.1.0
|
|
* Github: https://github.com/zhw2590582/ArtPlayer
|
|
* (c) 2017-2026 Harvey Zhao
|
|
* Released under the MIT License.
|
|
*/
|
|
!function(e,t){"object"===typeof exports&&"undefined"!==typeof module?module.exports=t():"function"==typeof define&&define.amd?(t.artplayerPluginChromecast=t(),define(function(){return t.artplayerPluginChromecast})):(e="undefined"!==typeof globalThis?globalThis:e||self).artplayerPluginChromecast=t()}(this,function(){"use strict";var e=(e,t,n)=>new Promise((o,a)=>{var c=e=>{try{i(n.next(e))}catch(t){a(t)}},s=e=>{try{i(n.throw(e))}catch(t){a(t)}},i=e=>e.done?o(e.value):Promise.resolve(e.value).then(c,s);i((n=n.apply(e,t)).next())});return function(t){let n=!1,o=null,a=null;const c=e=>{const t=document.querySelector(".art-icon-cast");if(t)switch(e){case"connected":t.style.color="red";break;case"connecting":case"disconnecting":t.style.color="orange";break;default:t.style.color="white"}},s=()=>new Promise((e,s)=>{var i;window.__onGCastApiAvailable=i=>{if(i){const s=window.cast.framework.CastContext.getInstance();s.setOptions({receiverApplicationId:window.chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,autoJoinPolicy:window.chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED}),s.addEventListener(window.cast.framework.CastContextEventType.SESSION_STATE_CHANGED,e=>{var n,s,i,l,r;const d=window.cast.framework.SessionState;switch(a=e.sessionState,o=e.session,e.sessionState){case d.NO_SESSION:null==(n=t.onStateChange)||n.call(t,"disconnected"),c("disconnected");break;case d.SESSION_STARTING:null==(s=t.onStateChange)||s.call(t,"connecting"),c("connecting");break;case d.SESSION_STARTED:null==(i=t.onStateChange)||i.call(t,"connected"),c("connected");break;case d.SESSION_ENDING:null==(l=t.onStateChange)||l.call(t,"disconnecting"),c("disconnecting");break;case d.SESSION_RESUMED:null==(r=t.onStateChange)||r.call(t,"connected"),c("connected")}}),s.addEventListener(window.cast.framework.CastContextEventType.CAST_STATE_CHANGED,e=>{var n,o,a;const c=window.cast.framework.CastState;switch(e.castState){case c.NO_DEVICES_AVAILABLE:null==(n=t.onCastAvailable)||n.call(t,!1);break;case c.NOT_CONNECTED:null==(o=t.onCastAvailable)||o.call(t,!0);break;case c.CONNECTING:case c.CONNECTED:null==(a=t.onCastAvailable)||a.call(t,!0)}}),n=!0,e()}else s(new Error("Cast API is not available"))},window.chrome&&window.chrome.cast||(i=t.sdk||"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1",new Promise((e,t)=>{const n=document.createElement("script");n.src=i,n.onload=e,n.onerror=t,document.body.appendChild(n)})).catch(s)}),i=(e,n)=>{const o=t.url||e.option.url,a=new window.chrome.cast.media.MediaInfo(o,t.mimeType||function(e){return{mp4:"video/mp4",webm:"video/webm",ogg:"video/ogg",ogv:"video/ogg",mp3:"audio/mp3",wav:"audio/wav",flv:"video/x-flv",mov:"video/quicktime",avi:"video/x-msvideo",wmv:"video/x-ms-wmv",mpd:"application/dash+xml",m3u8:"application/x-mpegURL"}[e.split("?")[0].split("#")[0].split(".").pop().toLowerCase()]||"application/octet-stream"}(o)),c=new window.chrome.cast.media.LoadRequest(a);n.loadMedia(c).then(()=>{var n;e.notice.show="Casting started",null==(n=t.onCastStart)||n.call(t)}).catch(n=>{var o;throw e.notice.show="Error casting media",null==(o=t.onError)||o.call(t,n),n})};return c=>e(null,null,function*(){return c.controls.add({name:"chromecast",position:"right",tooltip:"Chromecast",html:`<i class="art-icon art-icon-cast">${t.icon||'<svg height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M512 96H64v99c-13-2-26.4-3-40-3H0V96C0 60.7 28.7 32 64 32H512c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H288V456c0-13.6-1-27-3-40H512V96zM24 224c128.1 0 232 103.9 232 232c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-101.6-82.4-184-184-184c-13.3 0-24-10.7-24-24s10.7-24 24-24zm8 192a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM0 344c0-13.3 10.7-24 24-24c75.1 0 136 60.9 136 136c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-48.6-39.4-88-88-88c-13.3 0-24-10.7-24-24z"/></svg>'}</i>`,click:()=>e(null,null,function*(){var e,a;if(!n)try{yield s()}catch(r){throw c.notice.show="Failed to initialize Cast API",null==(e=t.onError)||e.call(t,r),r}const l=window.cast.framework.CastContext.getInstance();if(o)i(c,o);else try{const e=yield l.requestSession();i(c,e)}catch(r){throw c.notice.show="Error connecting to cast session",null==(a=t.onError)||a.call(t,r),r}})}),{name:"artplayerPluginChromecast",getCastState:()=>a,isCasting:()=>null!==o}})}});
|