videojs / video.js

Video.js - open source HTML5 video player
https://videojs.com
Other
38.06k stars 7.45k forks source link

Implementation of Video.js in Nextjs and Reactjs #8588

Open aminronak007 opened 8 months ago

aminronak007 commented 8 months ago

Description

I have implemented video.js library in my project and its working successfully also. But when i am trying to fetch and load more videos i.e. upto 120 to 140 videos then my app is getting crashed. So i am not getting any solution how to solve or prevent my web app from crashing.

This is my code. What should i do to prevent my web app from crashing.

Reduced test case

https:///no-url.com

Steps to reproduce

const LukPlayer = memo((props) => { const videoRef = useRef(null) const playerRef = useRef(null) const observerRef = useRef(null) const { options, onReady, data, commentFlag, flag } = props

const dispatch = useDispatch()

const [playing, setCurrentPlaying] = useState([])
const [sources, setSources] = useState([])

const { user } = useSelector((state) => state.user)

useEffect(() => {
  if (
    options?.sources !== sources &&
    !options?.sources[0]?.src?.includes('undefined')
  ) {
    setSources(options?.sources)
  }
}, [options?.sources])

// check if you are on client side
const isClient = typeof window !== 'undefined'

function check_iOS() {
  return (
    [
      'iPad Simulator',
      'iPhone Simulator',
      'iPod Simulator',
      'iPad',
      'iPhone',
      'iPod',
    ].includes(navigator.platform) ||
    // iPad on iOS 13 detection
    /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
  )
}

let ios = isClient ? check_iOS() : ''

// Add event listener for spacebar key press
useEffect(() => {
  const handleKeyPress = async (event) => {
    if (event.code === 'Space') {
      event.preventDefault()
      const player = playerRef.current
      if (player) {
        if (player?.paused()) {
          // add support for ios non user interaction policy
          // if (!ios) {
          await player?.play()
          // }
          //end ios support
        } else {
          // if (!ios) {
          player?.pause()
          // }
        }
      }
    }
  }

  // check if the video element is in view
  const checkIfVideoInView = (entries) => {
    entries?.forEach((entry) => {
      if (entry.isIntersecting) {
        // if the video is in view, attach keydown event listener to play/pause
        document.addEventListener('keydown', handleKeyPress)
      } else {
        // if the video is not in view, remove keydown event listener
        document.removeEventListener('keydown', handleKeyPress)
      }
    })
  }
  checkIfVideoInView()

  return () => {
    document.removeEventListener('keydown', handleKeyPress)
    observerRef.current.disconnect()
  }
}, [commentFlag, flag === 'create' && options, videoRef])

useEffect(() => {
  // Make sure Video.js player is only initialized once
  if (!playerRef.current) {
    // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
    const videoElement = document.createElement('video-js')

    videoElement?.classList.add('vjs-big-play-centered')
    videoRef?.current.appendChild(videoElement)

    let opt =
      options?.sources !== sources &&
      !options?.sources[0]?.src?.includes('undefined') &&
      options

    const player = videojs(videoElement, opt, () => {
      onReady && onReady(player)
    })
    playerRef.current = player

    // Event listener for the 'ended' event
    player.on('ended', () => {
      onVideoEnd()
    })

    // You could update an existing player in the `else` block here
    // on prop change, for example:
  } else {
    const player = playerRef?.current

    player?.autoplay(options.autoplay)
    if (sources?.length > 0) {
      player?.src(sources)
    }

    player.name_ = data
  }

  // create an observer and observe the element
  const videoNode = videoRef.current

  const observerOptions = {
    root: null,
    rootMargin: '0px',
    threshold: 0.5,
  }
  const player = playerRef.current

  observerRef.current = new IntersectionObserver((entries) => {
    entries.forEach(async (entry) => {
      if (entry.isIntersecting) {
        // add support for ios non user interaction policy
        // if (!ios) {
        await player?.play()
        // }
        //end ios support
        player.name_ = data
        // set into state the currently playing video
        setCurrentPlaying(player.name_)
      } else {
        // if (!ios) {
        player?.pause()
        // }
      }
    })
  }, observerOptions)
  observerRef.current.observe(videoNode)

  return () => {
    playerRef.current?.dispose()
    playerRef.current = null
    observerRef.current.disconnect()
  }
}, [commentFlag, flag === 'create' && options, playerRef])

const view = async (e) => {
  if (user?.token) {
    await dispatch(viewVideo(e))
  }
}

useEffect(() => {
  dispatch(setPlaying(playing))
  if (playing?.id) {
    view(playing)
  }
}, [playing?.id])

return (
  <div data-vjs-player>
    <div className={style.luk_player_wrapper} ref={videoRef} />
  </div>
)

})

export default LukPlayer

Errors

Error Code: Out of memory

What version of Video.js are you using?

8.0.4

Video.js plugins used.

8.0.4

What browser(s) including version(s) does this occur with?

Chrome

What OS(es) and version(s) does this occur with?

Windows 11

welcome[bot] commented 8 months ago

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.