88 submitComponentEvent ,
99} from '../client/ophan/ophan' ;
1010import { getZIndex } from '../lib/getZIndex' ;
11+ import { generateImageURL } from '../lib/image' ;
1112import { useIsInView } from '../lib/useIsInView' ;
1213import { useShouldAdapt } from '../lib/useShouldAdapt' ;
1314import type { CustomPlayEventDetail } from '../lib/video' ;
@@ -60,13 +61,24 @@ const dispatchOphanAttentionEvent = (
6061 document . dispatchEvent ( event ) ;
6162} ;
6263
64+ const getOptimisedPosterImage = ( mainImage : string ) : string => {
65+ const resolution = window . devicePixelRatio >= 2 ? 'high' : 'low' ;
66+
67+ return generateImageURL ( {
68+ mainImage,
69+ imageWidth : 940 , // The widest a looping video can be: Flexible special, giga-boosted
70+ resolution,
71+ aspectRatio : '5:4' ,
72+ } ) ;
73+ } ;
74+
6375type Props = {
6476 src : string ;
6577 atomId : string ;
6678 uniqueId : string ;
67- width : number ;
6879 height : number ;
69- image : string ;
80+ width : number ;
81+ posterImage : string ;
7082 fallbackImage : CardPictureProps [ 'mainImage' ] ;
7183 fallbackImageSize : CardPictureProps [ 'imageSize' ] ;
7284 fallbackImageLoading : CardPictureProps [ 'loading' ] ;
@@ -78,9 +90,9 @@ export const LoopVideo = ({
7890 src,
7991 atomId,
8092 uniqueId,
81- width,
8293 height,
83- image,
94+ width,
95+ posterImage,
8496 fallbackImage,
8597 fallbackImageSize,
8698 fallbackImageLoading,
@@ -94,9 +106,7 @@ export const LoopVideo = ({
94106 const [ isMuted , setIsMuted ] = useState ( true ) ;
95107 const [ showPlayIcon , setShowPlayIcon ] = useState ( false ) ;
96108 const [ preloadPartialData , setPreloadPartialData ] = useState ( false ) ;
97- const [ posterImage , setPosterImage ] = useState < string | undefined > (
98- undefined ,
99- ) ;
109+ const [ showPosterImage , setShowPosterImage ] = useState < boolean > ( false ) ;
100110 const [ currentTime , setCurrentTime ] = useState ( 0 ) ;
101111 const [ playerState , setPlayerState ] =
102112 useState < ( typeof PLAYER_STATES ) [ number ] > ( 'NOT_STARTED' ) ;
@@ -135,11 +145,11 @@ export const LoopVideo = ({
135145 . catch ( ( error : Error ) => {
136146 // Autoplay failed
137147 logAndReportError ( src , error ) ;
138- setPosterImage ( image ) ;
148+ setShowPosterImage ( true ) ;
139149 setPlayerState ( 'PAUSED_BY_BROWSER' ) ;
140150 } ) ;
141151 }
142- } , [ src , image ] ) ;
152+ } , [ src ] ) ;
143153
144154 const pauseVideo = (
145155 reason : Extract <
@@ -381,9 +391,9 @@ export const LoopVideo = ({
381391 isAutoplayAllowed === false ||
382392 ( isInView === false && ! hasBeenInView )
383393 ) {
384- setPosterImage ( image ) ;
394+ setShowPosterImage ( true ) ;
385395 }
386- } , [ isAutoplayAllowed , isInView , hasBeenInView , image ] ) ;
396+ } , [ isAutoplayAllowed , isInView , hasBeenInView ] ) ;
387397
388398 /**
389399 * We almost always want to preload some of the video data. If a user has prefers-reduced-motion
@@ -506,6 +516,10 @@ export const LoopVideo = ({
506516
507517 const AudioIcon = isMuted ? SvgAudioMute : SvgAudio ;
508518
519+ const optimisedPosterImage = showPosterImage
520+ ? getOptimisedPosterImage ( posterImage )
521+ : undefined ;
522+
509523 return (
510524 < figure
511525 ref = { setNode }
@@ -519,7 +533,7 @@ export const LoopVideo = ({
519533 uniqueId = { uniqueId }
520534 width = { width }
521535 height = { height }
522- posterImage = { posterImage }
536+ posterImage = { optimisedPosterImage }
523537 FallbackImageComponent = { FallbackImageComponent }
524538 currentTime = { currentTime }
525539 setCurrentTime = { setCurrentTime }
0 commit comments