mirror of
https://github.com/immich-app/immich.git
synced 2025-02-03 01:22:44 +01:00
feat: resolution selection and default preview playback for 360° panorama videos (#15747)
* original/preview switching in photo-sphere-viewer 1. default to preview in photo-sphere-viewer video mode 2. install and integrate @photo-sphere-viewer/settings-plugin & @photo-sphere-viewer/resolution-plugin * fix lint errors
This commit is contained in:
parent
92dff839d0
commit
08db77db23
5 changed files with 66 additions and 11 deletions
web
21
web/package-lock.json
generated
21
web/package-lock.json
generated
|
@ -16,6 +16,8 @@
|
|||
"@mdi/js": "^7.4.47",
|
||||
"@photo-sphere-viewer/core": "^5.11.5",
|
||||
"@photo-sphere-viewer/equirectangular-video-adapter": "^5.11.5",
|
||||
"@photo-sphere-viewer/resolution-plugin": "^5.11.5",
|
||||
"@photo-sphere-viewer/settings-plugin": "^5.11.5",
|
||||
"@photo-sphere-viewer/video-plugin": "^5.11.5",
|
||||
"@zoom-image/svelte": "^0.3.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
|
@ -1669,6 +1671,25 @@
|
|||
"@photo-sphere-viewer/video-plugin": "5.11.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@photo-sphere-viewer/resolution-plugin": {
|
||||
"version": "5.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@photo-sphere-viewer/resolution-plugin/-/resolution-plugin-5.11.5.tgz",
|
||||
"integrity": "sha512-Dbvp5bBtozD3IWt1Q0wORVaZBcB1bV9xUeoOS9A7F7b3EkQ2pkC5/jot/1AyM4wtU5wJ63NWHskQ1d7m6WWazQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@photo-sphere-viewer/core": "5.11.5",
|
||||
"@photo-sphere-viewer/settings-plugin": "5.11.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@photo-sphere-viewer/settings-plugin": {
|
||||
"version": "5.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@photo-sphere-viewer/settings-plugin/-/settings-plugin-5.11.5.tgz",
|
||||
"integrity": "sha512-ZgYaWjiBMhsoRH5ddW3h+v4J4LPmofsT7BBRq5UCssWw2Fsrvv7mFFRi4UbZ1qzeKmvNUOr8BaFQgX1ZLvUWfQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@photo-sphere-viewer/core": "5.11.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@photo-sphere-viewer/video-plugin": {
|
||||
"version": "5.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@photo-sphere-viewer/video-plugin/-/video-plugin-5.11.5.tgz",
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
"@mdi/js": "^7.4.47",
|
||||
"@photo-sphere-viewer/core": "^5.11.5",
|
||||
"@photo-sphere-viewer/equirectangular-video-adapter": "^5.11.5",
|
||||
"@photo-sphere-viewer/resolution-plugin": "^5.11.5",
|
||||
"@photo-sphere-viewer/settings-plugin": "^5.11.5",
|
||||
"@photo-sphere-viewer/video-plugin": "^5.11.5",
|
||||
"@zoom-image/svelte": "^0.3.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{:then [data, { default: PhotoSphereViewer }]}
|
||||
<PhotoSphereViewer
|
||||
panorama={data}
|
||||
originalImageUrl={isWebCompatibleImage(asset) ? getAssetOriginalUrl(asset.id) : undefined}
|
||||
originalPanorama={isWebCompatibleImage(asset) ? getAssetOriginalUrl(asset.id) : undefined}
|
||||
/>
|
||||
{:catch}
|
||||
{$t('errors.failed_to_load_asset')}
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
type AdapterConstructor,
|
||||
type PluginConstructor,
|
||||
} from '@photo-sphere-viewer/core';
|
||||
import { SettingsPlugin } from '@photo-sphere-viewer/settings-plugin';
|
||||
import { ResolutionPlugin } from '@photo-sphere-viewer/resolution-plugin';
|
||||
import '@photo-sphere-viewer/core/index.css';
|
||||
import '@photo-sphere-viewer/settings-plugin/index.css';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
|
||||
interface Props {
|
||||
panorama: string | { source: string };
|
||||
originalImageUrl?: string;
|
||||
originalPanorama?: string | { source: string };
|
||||
adapter?: AdapterConstructor | [AdapterConstructor, unknown];
|
||||
plugins?: (PluginConstructor | [PluginConstructor, unknown])[];
|
||||
navbar?: boolean;
|
||||
}
|
||||
|
||||
let { panorama, originalImageUrl, adapter = EquirectangularAdapter, plugins = [], navbar = false }: Props = $props();
|
||||
let { panorama, originalPanorama, adapter = EquirectangularAdapter, plugins = [], navbar = false }: Props = $props();
|
||||
|
||||
let container: HTMLDivElement | undefined = $state();
|
||||
let viewer: Viewer;
|
||||
|
@ -30,9 +33,33 @@
|
|||
|
||||
viewer = new Viewer({
|
||||
adapter,
|
||||
plugins,
|
||||
plugins: [
|
||||
SettingsPlugin,
|
||||
[
|
||||
ResolutionPlugin,
|
||||
{
|
||||
defaultResolution: $alwaysLoadOriginalFile && originalPanorama ? 'original' : 'default',
|
||||
resolutions: [
|
||||
{
|
||||
id: 'default',
|
||||
label: 'Default',
|
||||
panorama,
|
||||
},
|
||||
...(originalPanorama
|
||||
? [
|
||||
{
|
||||
id: 'original',
|
||||
label: 'Original',
|
||||
panorama: originalPanorama,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
],
|
||||
...plugins,
|
||||
],
|
||||
container,
|
||||
panorama,
|
||||
touchmoveTwoFingers: false,
|
||||
mousewheelCtrlKey: false,
|
||||
navbar,
|
||||
|
@ -40,15 +67,14 @@
|
|||
maxFov: 120,
|
||||
fisheye: false,
|
||||
});
|
||||
const resolutionPlugin = viewer.getPlugin(ResolutionPlugin) as ResolutionPlugin;
|
||||
|
||||
if (originalImageUrl && !$alwaysLoadOriginalFile) {
|
||||
if (originalPanorama && !$alwaysLoadOriginalFile) {
|
||||
const zoomHandler = ({ zoomLevel }: events.ZoomUpdatedEvent) => {
|
||||
// zoomLevel range: [0, 100]
|
||||
if (Math.round(zoomLevel) >= 75) {
|
||||
// Replace the preview with the original
|
||||
viewer.setPanorama(originalImageUrl, { showLoader: false, speed: 150 }).catch(() => {
|
||||
viewer.setPanorama(panorama, { showLoader: false, speed: 0 }).catch(() => {});
|
||||
});
|
||||
void resolutionPlugin.setResolution('original');
|
||||
viewer.removeEventListener(events.ZoomUpdatedEvent.type, zoomHandler);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { getAssetOriginalUrl } from '$lib/utils';
|
||||
import { getAssetPlaybackUrl, getAssetOriginalUrl } from '$lib/utils';
|
||||
import { fade } from 'svelte/transition';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
@ -22,7 +22,13 @@
|
|||
{#await modules}
|
||||
<LoadingSpinner />
|
||||
{:then [PhotoSphereViewer, adapter, videoPlugin]}
|
||||
<PhotoSphereViewer panorama={{ source: getAssetOriginalUrl(assetId) }} plugins={[videoPlugin]} {adapter} navbar />
|
||||
<PhotoSphereViewer
|
||||
panorama={{ source: getAssetPlaybackUrl(assetId) }}
|
||||
originalPanorama={{ source: getAssetOriginalUrl(assetId) }}
|
||||
plugins={[videoPlugin]}
|
||||
{adapter}
|
||||
navbar
|
||||
/>
|
||||
{:catch}
|
||||
{$t('errors.failed_to_load_asset')}
|
||||
{/await}
|
||||
|
|
Loading…
Reference in a new issue