diff --git a/web/src/lib/components/asset-viewer/video-native-viewer.svelte b/web/src/lib/components/asset-viewer/video-native-viewer.svelte index 4b8bb40f77..6b5c77a189 100644 --- a/web/src/lib/components/asset-viewer/video-native-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-native-viewer.svelte @@ -7,12 +7,10 @@ import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { loopVideo as loopVideoPreference, videoViewerMuted, videoViewerVolume } from '$lib/stores/preferences.store'; import { getAssetPlaybackUrl, getAssetThumbnailUrl } from '$lib/utils'; - import { handleError } from '$lib/utils/handle-error'; import { AssetMediaSize } from '@immich/sdk'; import { onDestroy, onMount } from 'svelte'; import type { SwipeCustomEvent } from 'svelte-gestures'; import { swipe } from 'svelte-gestures'; - import { t } from 'svelte-i18n'; import { fade } from 'svelte/transition'; interface Props { @@ -40,7 +38,6 @@ let videoPlayer: HTMLVideoElement | undefined = $state(); let isLoading = $state(true); let assetFileUrl = $state(''); - let forceMuted = $state(false); let isScrubbing = $state(false); let showVideo = $state(false); @@ -49,7 +46,6 @@ showVideo = true; assetFileUrl = getAssetPlaybackUrl({ id: assetId, cacheKey }); if (videoPlayer) { - forceMuted = false; videoPlayer.load(); } }); @@ -67,23 +63,27 @@ onVideoStarted(); } } catch (error) { - if (error instanceof DOMException && error.name === 'NotAllowedError' && !forceMuted) { + if (error instanceof DOMException && error.name === 'NotAllowedError') { await tryForceMutedPlay(video); return; } - handleError(error, $t('errors.unable_to_play_video')); + // auto-play failed } finally { isLoading = false; } }; const tryForceMutedPlay = async (video: HTMLVideoElement) => { + if (video.muted) { + return; + } + try { video.muted = true; await handleCanPlay(video); - } catch (error) { - handleError(error, $t('errors.unable_to_play_video')); + } catch { + // muted auto-play failed } }; @@ -134,18 +134,14 @@ onswipe={onSwipe} oncanplay={(e) => handleCanPlay(e.currentTarget)} onended={onVideoEnded} - onvolumechange={(e) => { - if (!forceMuted) { - $videoViewerMuted = e.currentTarget.muted; - } - }} + onvolumechange={(e) => ($videoViewerMuted = e.currentTarget.muted)} onseeking={() => (isScrubbing = true)} onseeked={() => (isScrubbing = false)} onplaying={(e) => { e.currentTarget.focus(); }} onclose={() => onClose()} - muted={forceMuted || $videoViewerMuted} + muted={$videoViewerMuted} bind:volume={$videoViewerVolume} poster={getAssetThumbnailUrl({ id: assetId, size: AssetMediaSize.Preview, cacheKey })} src={assetFileUrl}