Skip to content

Instantly share code, notes, and snippets.

@iamkevingreen
Last active November 16, 2023 22:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamkevingreen/f0a4eceb320741572769b3cde8303d4c to your computer and use it in GitHub Desktop.
Save iamkevingreen/f0a4eceb320741572769b3cde8303d4c to your computer and use it in GitHub Desktop.
import React, {useState, useEffect, useRef} from 'react'
import classNames from 'classnames'
import {useIntersection} from 'use-intersection'
const Video = ({
video,
poster,
posterWidth = 1920,
posterFitMode = 'preserve',
className,
showControls = false,
autoPlay = true,
forcePlay = false,
playsInline = true,
loop = true,
muted = true,
...props
}) => {
const [notSupported, setNotSupported] = useState(false)
const videoEl = useRef(null)
const isIntersecting = useIntersection(videoEl, {
once: true,
threshold: 0,
})
//
// === Setup HLS + Plyr ===
//
useEffect(async () => {
let hls
// Only run if we're in browser
if (!videoEl.current) return
const canStream = videoEl.current.canPlayType(
'application/vnd.apple.mpegurl',
)
const {default: Hls} = await import('hls.js')
// If we can play HLS, leave it alone
if (!canStream) {
if (Hls.isSupported()) {
hls = new Hls()
hls.loadSource(src)
hls.attachMedia(videoEl.current)
} else {
setNotSupported(true)
}
}
videoEl.current.volume = 0
if (forcePlay) {
videoEl.current.play()
}
return () => {
if (hls) {
hls.destroy()
}
}
}, [videoEl])
useEffect(() => {
if (isIntersecting && videoEl.current) {
videoEl.current.play()
}
}, [videoEl, isIntersecting])
const posterImage =
poster ||
`https://image.mux.com/${
video.playbackId
}/thumbnail.jpg?width=${posterWidth}&fit_mode=${posterFitMode}&time=${
video.thumbTime || 0
}`
const src = `https://stream.mux.com/${video.playbackId}.m3u8`
if (notSupported) {
return (
<picture className="db x">
<img className="db x" src={posterImage} />
</picture>
)
}
return (
<div className={classNames('db x', className)}>
<video
{...props}
controls={showControls}
ref={videoEl}
poster={posterImage}
className="db x"
playsInline={playsInline}
loop={loop}
muted={muted}
src={src}
/>
</div>
)
}
export default Video
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment