diff --git a/package.json b/package.json index 2ac0a3536..9d00a98e6 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.61.0", "@stremio/stremio-icons": "5.10.0", - "@stremio/stremio-video": "0.0.90", + "@stremio/stremio-video": "0.0.93", "a-color-picker": "1.2.1", "bowser": "2.14.1", "buffer": "6.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a75ed5c6..7d8ed66c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: 5.10.0 version: 5.10.0 '@stremio/stremio-video': - specifier: 0.0.90 - version: 0.0.90 + specifier: 0.0.93 + version: 0.0.93 a-color-picker: specifier: 1.2.1 version: 1.2.1 @@ -1417,6 +1417,10 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@stremio/libass-wasm@https://github.com/Stremio/JavascriptSubtitlesOctopus/releases/download/v4.2.6/stremio-libass-wasm-4.2.6.tgz': + resolution: {integrity: sha512-oHIud2ukVu4/tfrQNrd8vzd6Su0zV8FCatLjuEznf533AW+hj59Eg1g9y2mllpd+GmXrSzf/DNr9jJhYQAg5Gg==, tarball: https://github.com/Stremio/JavascriptSubtitlesOctopus/releases/download/v4.2.6/stremio-libass-wasm-4.2.6.tgz} + version: 4.2.6 + '@stremio/stremio-colors@5.2.0': resolution: {integrity: sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg==} @@ -1426,8 +1430,8 @@ packages: '@stremio/stremio-icons@5.10.0': resolution: {integrity: sha512-Zw/vGC3D2yeQfk8xv/tfMJTDvbCPOI91tBg4XpR2+EgbZSX8Xvm7Vz457PIhFPhTAwdOPHp0VX0M3gzjbt0zOg==} - '@stremio/stremio-video@0.0.90': - resolution: {integrity: sha512-5I4T6GRFaK9fbPwz98bBNScBNpWBSrczkFt+qmhEJ8Tq9INdaah5OQd+hsZTEJIs7dR28M5nvMHpB4owx1UWDg==} + '@stremio/stremio-video@0.0.93': + resolution: {integrity: sha512-/R6rHh/lekHK4ZjCeMb4O27iOXQo36jek0kfzbbpYw/3yXf9yWxX+LWK5hajBFeZWitOm8GMSnDlkb31LIeIeg==} '@stylistic/eslint-plugin-jsx@4.4.1': resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==} @@ -6483,6 +6487,8 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@stremio/libass-wasm@https://github.com/Stremio/JavascriptSubtitlesOctopus/releases/download/v4.2.6/stremio-libass-wasm-4.2.6.tgz': {} + '@stremio/stremio-colors@5.2.0': {} '@stremio/stremio-core-web@0.61.0': @@ -6491,8 +6497,9 @@ snapshots: '@stremio/stremio-icons@5.10.0': {} - '@stremio/stremio-video@0.0.90': + '@stremio/stremio-video@0.0.93': dependencies: + '@stremio/libass-wasm': https://github.com/Stremio/JavascriptSubtitlesOctopus/releases/download/v4.2.6/stremio-libass-wasm-4.2.6.tgz buffer: 6.0.3 color: 4.2.3 deep-freeze: 0.0.1 diff --git a/src/common/Platform/shell/shell.d.ts b/src/common/Platform/shell/shell.d.ts index 5c1b8eb93..3603b9a8c 100644 --- a/src/common/Platform/shell/shell.d.ts +++ b/src/common/Platform/shell/shell.d.ts @@ -23,6 +23,7 @@ interface Shell { type ShellCapabilities = { gpuVideoProcessing: boolean; + nativeAssSubtitles: boolean; }; type ShellState = { diff --git a/src/common/Platform/shell/useShell.ts b/src/common/Platform/shell/useShell.ts index a672fa990..4d69ea610 100644 --- a/src/common/Platform/shell/useShell.ts +++ b/src/common/Platform/shell/useShell.ts @@ -43,6 +43,7 @@ const useShell = (): Shell => { }); const [capabilities, setCapabilities] = useState({ gpuVideoProcessing: false, + nativeAssSubtitles: false, }); const on = (name: string, listener: (arg: any) => void) => events.on(name, listener); @@ -91,15 +92,18 @@ const useShell = (): Shell => { if (event.type === ShellEventType.INIT) { const { data } = event as ShellEventInit; - const [, [,,, version], [,,, gpuVideoProcessing] = []] = data.transport.properties; + const shellProperties = Object.fromEntries(data.transport.properties + .filter((property) => property.length >= 4 && property[1]) + .map(([, name,, value]) => [name, value])); setState((state) => ({ ...state, initialized: true, - version, + version: shellProperties.shellVersion ?? null, })); setCapabilities({ - gpuVideoProcessing: gpuVideoProcessing === 'true', + gpuVideoProcessing: shellProperties.gpuVideoProcessing === 'true', + nativeAssSubtitles: shellProperties.nativeAssSubtitles === 'true', }); } diff --git a/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.less b/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.less index 600b79658..58700053d 100644 --- a/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.less +++ b/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.less @@ -21,8 +21,16 @@ flex-direction: column; gap: 0.25rem; + .variant-title { + display: flex; + align-items: center; + gap: 0.5rem; + min-width: 0; + } + .variant-label { flex: 1; + min-width: 0; font-size: 1.1rem; line-height: 1.5rem; color: var(--primary-foreground-color); @@ -31,6 +39,16 @@ overflow: hidden; } + .ass-badge { + flex: none; + padding: 0.1rem 0.3rem; + border: 1px solid var(--color-placeholder-text); + border-radius: 0.25rem; + font-size: 0.65rem; + line-height: 0.8rem; + color: var(--color-placeholder-text); + } + .variant-origin { font-size: 0.9rem; color: var(--color-placeholder-text); diff --git a/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.tsx b/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.tsx index 9bd8f909c..bc9bc5268 100644 --- a/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.tsx +++ b/src/routes/Player/SubtitlesMenu/SubtitleVariant/SubtitleVariant.tsx @@ -19,6 +19,7 @@ type SubtitlesTrack = { embedded?: boolean, local?: boolean, exclusive?: boolean, + ass?: boolean, }; type Props = { @@ -28,6 +29,7 @@ type Props = { }; const hasValidLabel = (label?: string) => label && label.length > 0 && !label.startsWith('http'); +const ASS_BADGE = 'ASS'; const SubtitleVariant = ({ track, selected, onSelect }: Props) => { const { t } = useTranslation(); @@ -73,8 +75,11 @@ const SubtitleVariant = ({ track, selected, onSelect }: Props) => { className={classNames(styles['variant-option'], { 'selected': selected })} >
-
- {variantLabel} +
+
+ {variantLabel} +
+ {track.ass ?
{ASS_BADGE}
: null}
{t(track.origin)} diff --git a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js index a71969bd5..d40cf0874 100644 --- a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js +++ b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js @@ -226,7 +226,7 @@ const SubtitlesMenu = React.memo(React.forwardRef((props, ref) => { step={25} min={SUBTITLES_SIZES[0]} max={SUBTITLES_SIZES[SUBTITLES_SIZES.length - 1]} - disabled={(props.selectedSubtitlesTrackId && props.subtitlesSize === null) || (props.selectedExtraSubtitlesTrackId && props.extraSubtitlesSize === null)} + disabled={props.assSubtitlesStylingActive || (props.selectedSubtitlesTrackId && props.subtitlesSize === null) || (props.selectedExtraSubtitlesTrackId && props.extraSubtitlesSize === null)} onChange={onSubtitlesSizeChanged} /> { step={1} min={0} max={100} - disabled={(props.selectedSubtitlesTrackId && props.subtitlesOffset === null) || (props.selectedExtraSubtitlesTrackId && props.extraSubtitlesOffset === null)} + disabled={props.assSubtitlesStylingActive || (props.selectedSubtitlesTrackId && props.subtitlesOffset === null) || (props.selectedExtraSubtitlesTrackId && props.extraSubtitlesOffset === null)} onChange={onSubtitlesOffsetChanged} />
@@ -255,7 +255,8 @@ SubtitlesMenu.propTypes = { subtitlesTracks: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired, lang: PropTypes.string.isRequired, - origin: PropTypes.string.isRequired + origin: PropTypes.string.isRequired, + ass: PropTypes.bool })), selectedSubtitlesTrackId: PropTypes.string, subtitlesOffset: PropTypes.number, @@ -268,12 +269,14 @@ SubtitlesMenu.propTypes = { url: PropTypes.string, embedded: PropTypes.bool, local: PropTypes.bool, - exclusive: PropTypes.bool + exclusive: PropTypes.bool, + ass: PropTypes.bool })), selectedExtraSubtitlesTrackId: PropTypes.string, extraSubtitlesOffset: PropTypes.number, extraSubtitlesDelay: PropTypes.number, extraSubtitlesSize: PropTypes.number, + assSubtitlesStylingActive: PropTypes.bool, onSubtitlesTrackSelected: PropTypes.func, onExtraSubtitlesTrackSelected: PropTypes.func, onSubtitlesOffsetChanged: PropTypes.func, diff --git a/src/routes/Player/useSubtitles.d.ts b/src/routes/Player/useSubtitles.d.ts index a38759628..36e788ad9 100644 --- a/src/routes/Player/useSubtitles.d.ts +++ b/src/routes/Player/useSubtitles.d.ts @@ -10,6 +10,7 @@ type SubtitleTrack = { embedded?: boolean, local?: boolean, exclusive?: boolean, + ass?: boolean, buffer?: ArrayBuffer, }; @@ -30,6 +31,7 @@ type VideoSubtitleState = { extraSubtitlesOffset: number | null, extraSubtitlesDelay: number | null, extraSubtitlesSize: number | null, + assSubtitlesStylingActive: boolean, }; type VideoEvents = { @@ -76,6 +78,7 @@ type SubtitlesMenuProps = { extraSubtitlesOffset: number | null, extraSubtitlesDelay: number | null, extraSubtitlesSize: number | null, + assSubtitlesStylingActive: boolean, onSubtitlesTrackSelected: (track: SubtitleTrack | null) => void, onExtraSubtitlesTrackSelected: (track: SubtitleTrack | null) => void, onSubtitlesOffsetChanged: (offset: number) => void, diff --git a/src/routes/Player/useSubtitles.ts b/src/routes/Player/useSubtitles.ts index 5f47eff22..3ab227a6a 100644 --- a/src/routes/Player/useSubtitles.ts +++ b/src/routes/Player/useSubtitles.ts @@ -560,6 +560,7 @@ const useSubtitles = ({ extraSubtitlesOffset: video.state.extraSubtitlesOffset, extraSubtitlesDelay: video.state.extraSubtitlesDelay, extraSubtitlesSize: video.state.extraSubtitlesSize, + assSubtitlesStylingActive: video.state.assSubtitlesStylingActive, onSubtitlesTrackSelected: selectEmbeddedTrack, onExtraSubtitlesTrackSelected: selectExtraTrack, onSubtitlesOffsetChanged: changeOffset, @@ -579,6 +580,7 @@ const useSubtitles = ({ video.state.extraSubtitlesOffset, video.state.extraSubtitlesSize, video.state.extraSubtitlesTracks, + video.state.assSubtitlesStylingActive, video.state.selectedExtraSubtitlesTrackId, video.state.selectedSubtitlesTrackId, video.state.subtitlesOffset, diff --git a/src/routes/Player/useVideo.js b/src/routes/Player/useVideo.js index c699f9fc5..817dff291 100644 --- a/src/routes/Player/useVideo.js +++ b/src/routes/Player/useVideo.js @@ -40,6 +40,7 @@ const useVideo = () => { extraSubtitlesTextColor: null, extraSubtitlesBackgroundColor: null, extraSubtitlesOutlineColor: null, + assSubtitlesStylingActive: false, fullscreen: null, }); diff --git a/src/routes/Settings/Player/Player.tsx b/src/routes/Settings/Player/Player.tsx index 29883e91d..317fd9aa9 100644 --- a/src/routes/Settings/Player/Player.tsx +++ b/src/routes/Settings/Player/Player.tsx @@ -66,6 +66,12 @@ const Player = forwardRef(({ profile }: Props, ref) => { {...subtitlesOutlineColorInput} /> + } - { - shell.active && - - } );