diff --git a/src/utils/videoFit.test.ts b/src/utils/videoFit.test.ts index 9390e8d4..5068526b 100644 --- a/src/utils/videoFit.test.ts +++ b/src/utils/videoFit.test.ts @@ -116,6 +116,18 @@ test.each([ tileSize: VIDEO_480_L, expected: "contain", }, + { + // Should default to cover if the initial size is 0:0. + // Or else it will cause a flash of "contain" mode until the real size is loaded, which can be jarring. + videoSize: VIDEO_480_L, + tileSize: { width: 0, height: 0 }, + expected: "cover", + }, + { + videoSize: { width: 0, height: 0 }, + tileSize: VIDEO_480_L, + expected: "cover", + }, ])( "videoFit$ returns $expected when videoSize is $videoSize and tileSize is $tileSize", ({ videoSize, tileSize, expected }) => { diff --git a/src/utils/videoFit.ts b/src/utils/videoFit.ts index c7b18f03..5f2cc2ce 100644 --- a/src/utils/videoFit.ts +++ b/src/utils/videoFit.ts @@ -36,6 +36,15 @@ export function videoFit$( // This is a reasonable default as it will ensure the video fills the tile, even if it means cropping. return "cover"; } + if ( + videoSize.width === 0 || + videoSize.height === 0 || + tileSize.width === 0 || + tileSize.height === 0 + ) { + // If we have invalid sizes (e.g. width or height is 0), default to cover to avoid black bars. + return "cover"; + } const videoAspectRatio = videoSize.width / videoSize.height; const tileAspectRatio = tileSize.width / tileSize.height;