Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions app/src/components/content/VideoPlayer.css
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,10 @@
display: none !important;
}

/* iOS Safari renders the video-js tech element 1px lower than its absolutely-positioned
.video-player container, leaving a 1px gap at the top and an overhang at the bottom
(issue #813). Same iOS-Safari feature-query technique used in LHighlightable.vue. */
@supports (-webkit-touch-callout: none) {
.video-player {
transform: translateY(-1px);
}
/* Safari renders the video 1px lower than its absolutely-positioned .video-player
container, leaving a 1px gap at the top and an overhang at the bottom (issue #813).
Affects Safari on both macOS and iOS but not Chrome/Firefox, so the component toggles
`.safari-shift-fix` using video.js's browser detection (IS_SAFARI || IS_IOS). */
.video-player.safari-shift-fix {
transform: translateY(-1px);
}
23 changes: 20 additions & 3 deletions app/src/components/content/VideoPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const autoPlay = queryParams.get("autoplay") === "true";
const autoFullscreen = queryParams.get("autofullscreen") === "true";
const keepAudioAlive = ref<HTMLAudioElement | null>(null);
const isRestoringTrack = ref<boolean>(false);
// Safari (macOS + iOS) renders the video 1px too low; corrected via CSS (issue #813).
const isSafariRendering = ref<boolean>(false);

// YouTube detection
const isYouTube = ref<boolean>(false);
Expand Down Expand Up @@ -144,6 +146,9 @@ onMounted(async () => {

const videojs = (await import("video.js")).default;

// Detect Safari for the 1px shift correction; same source used for nativeAudioTracks.
isSafariRendering.value = videojs.browser.IS_SAFARI || videojs.browser.IS_IOS;

// Lazy load videojs-youtube only if we're playing a YouTube video
if (isYouTube.value) {
await import("videojs-youtube");
Expand Down Expand Up @@ -566,7 +571,10 @@ watch(
:parent-image-bucket-id="content.parentImageBucketId"
/>

<div class="video-player absolute bottom-0 left-0 right-0 top-0">
<div
class="video-player absolute bottom-0 left-0 right-0 top-0"
:class="{ 'safari-shift-fix': isSafariRendering }"
>
<video
playsinline
ref="playerElement"
Expand All @@ -579,8 +587,17 @@ watch(
</div>

<!-- audio tag to keep player alive -->
<audio ref="keepAudioAlive" loop muted preload="auto" style="display: none">
<source src="../../assets/silence.wav" type="audio/wav" />
<audio
ref="keepAudioAlive"
loop
muted
preload="auto"
style="display: none"
>
<source
src="../../assets/silence.wav"
type="audio/wav"
/>
</audio>

<transition
Expand Down
Loading