OvenPlayer icon indicating copy to clipboard operation
OvenPlayer copied to clipboard

on('time') not working properly in react js

Open tejped opened this issue 4 years ago • 4 comments

Created a OvenPlayer instance using ovenplayer node library. import OvenPlayer from 'ovenplayer'

but on('time') event is not triggering as per mentioned in docs, for a 35sec video it trigger only thrice. can anyone help to resolve it. I need it should get trigger for every second.

My component is

import { useEffect, useState } from 'react'
import OvenPlayer from 'ovenplayer'
import dashjs from 'dashjs'

import VideoLoader from 'components/loader/VideoLoader'
import './OutputPlayer.scss'

const OutputPlayerOven = (props) => {
  const [loading, setLoading] = useState(true)
  const [showGoLiveButton, setShowGoLiveButton] = useState(false)
  const [sourceFile, setSourceFile] = useState(true)
  const [userSeek, setUserSeek] = useState(true)

  let ovenPlayer = null
  let reloadTimeout
  let posTimeout

  useEffect(() => {
    // OvenPlayer.debug(true)
    console.log('Start time=>', new Date())

    return () => {
      // cleaned up
      ovenPlayer = null
      clearTimeout(posTimeout)
    }
  }, [])

  useEffect(() => {
    if (props.playerConfig === 'file') setSourceFile(true)
    else setSourceFile(false)
  }, [props.playerConfig])

  const loadOvenPlayer = () => {
    // if (ovenPlayer) {
    //   ovenPlayer.remove()
    // }

    let source = [{
      label: `testStream`,
        type: 'webrtc',
        file: path,
    }]

    

    if (document.getElementById('player')) {
      ovenPlayer = OvenPlayer.create('player', {
        autoStart: true,
        controls: true,
        mute: true,
        autoFallback: true,
        currentProtocolOnly: false,
        showBigPlayButton: false,
        showSeekControl: false,
        disableSeekUI: false,
        hidePlaylistIcon: true,
        timecode: true,
        playbackRate: 1,
        playbackRates: [1],
        sources: source,
      })

      // Reload OvenPlayer when error occured.
      ovenPlayer.on('error', (error) => {
        // console.log('error =>', error)

        // Wait 2 sec and relaod.
        reloadTimeout = setTimeout(() => {
          loadOvenPlayer()
        }, 2000)
      })

      ovenPlayer.on('ready', () => {
        // getPosition()
      }) 
      ovenPlayer.on('metaChanged', (event) => {
        console.log('metaChanged =>', event);
        props.conenctMetaSocket()
      })
      ovenPlayer.on('stateChanged', (event) => {
        if (event.newstate === 'playing') {
          clearTimeout(reloadTimeout)
          console.log('Play time=>', new Date())
          setLoading(false)
        } else if (event.newstate === 'complete') {
          props.handlePlayEnd('ended')
          clearTimeout(posTimeout)
        }
      })
      ovenPlayer.on('seeked', () => {
        setLoading(false)
      })
      ovenPlayer.on('time', (event) => {
        console.log('time update =>', event)
        props.setCurrentPlayBack(event.position)
        // seekHandler(event)
      })
    }
  }

  const getPosition = () => {
    if(ovenPlayer) {
      let position = ovenPlayer.getPosition()
      console.log('position before if =>', position);
      if(position) {
        console.log('position =>', position);
        props.setCurrentPlayBack(position)
      }
    }

    posTimeout = setTimeout(() => {
      getPosition()
    }, 1000)
  }

  useEffect(() => {
    if ((props.link || props.sources.length) && props.playerConfig)
      loadOvenPlayer()
  }, [props.link, props.sources, sourceFile])

  const handleLiveClick = () => {
    if (!sourceFile) {
      setShowGoLiveButton(false)
    }
    const player = document.getElementById('player')
    // player.currentTime = player.duration
  }

  const seekHandler = (event) => {
    if (!sourceFile) {
      if (userSeek) {
        setUserSeek(false)
      } else {
        setShowGoLiveButton(true)
        console.log('handleVideoSeek =>', event.newstate, event.position, event.newstate - event.position);
        if (event.newstate - event.position < 60) {
          props.handleVideoSeek(undefined)
        } else {
          props.handleVideoSeek(event.position)
        }
      }
    }
  }

  return (
    <div className='outputPlayerWrapper'>
      {loading ? <VideoLoader /> : null}
      <div id='player' style={{ opacity: loading ? 0 : 1 }} />
      {showGoLiveButton ? (
        <div className='resumeLive' onClick={handleLiveClick}>
          <div className='resumeLiveIcon'></div>
          <span className='resumeLiveLabel'>Go Live</span>
        </div>
      ) : null}
    </div>
  )
}

export default OutputPlayerOven

tejped avatar Jan 20 '22 19:01 tejped

I made a quick React app and used your above component to load a 44 second MP4 video, and OvenPlayer 0.10.16 calls the .on('time') handler about 8 times per second all the way through. I'm not sure why you're getting a different result, but it seems to work fine here. Maybe WebRTC sources have a different .on('time') handler code path inside OvenPlayer? I don't have a WebRTC source to play back at the moment, but I would be interested to know if MP4 works for you, and if you find WebRTC works differently with the same component.

time update => {position: 0.881829, duration: 44.907}
OvenPlayer.js:94 time update => {position: 0.883301, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.131752, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.132822, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.382554, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.383326, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.63361, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.632622, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.884156, duration: 44.907}
OvenPlayer.js:94 time update => {position: 1.883692, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.134592, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.133098, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.384888, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.383369, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.634167, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.633918, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.998477, duration: 44.907}
OvenPlayer.js:94 time update => {position: 2.997704, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.246519, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.246944, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.497918, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.495937, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.751023, duration: 44.907}
OvenPlayer.js:94 time update => {position: 3.749183, duration: 44.907}
OvenPlayer.js:94 time update => {position: 4.000748, duration: 44.907}
...and so on...

Tangentially related, you may want to consider using React DOM Refs instead of a hardcoded <div id='player' .... This will let your component avoid embedding a unique ID and potentially colliding with another element of the same ID (perhaps a second instance of this very component). I ran into this in #245 and #248, but it's all working properly now as of the latest OvenPlayer release.

command-tab avatar Jan 20 '22 21:01 command-tab

Hi. There is no different .on('time') handler for WebRTC sources. I also tested with WebRTC stream, on average, a time event triggered 4 times per second. @tejped What happens when you play your stream with the simplest HTML+JS UNIT test, not with reactjs?

SangwonOh avatar Jan 21 '22 04:01 SangwonOh

Hi Guys, Thanks for quick response.

As you mentioned I tried with non webrtc source, where On('time') is working proper but initial latency is too long. In case of webrtc, latency is very low but on('time') is trigger only thrice for whole 35sec video. Is there any way to get it trigger for every second.

tejped avatar Jan 21 '22 04:01 tejped

@tejped What happens when you test with the code below? If the time event does not occur normally with this test, there may be a problem other than the player.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OvenPlayer</title>
</head>

<body>
    <!-- OvenPlayer will be initialized inside this element. -->
    <div id="player_id"></div>
    
    <!-- Load OvenPlayer via CDN -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ovenplayer.js"></script>

    <script>

        // Initialize OvenPlayer
        const player = OvenPlayer.create('player_id', {
            timecode: true,
            sources: [
                {
                    type: 'webrtc',
                    file: 'your stream'

                }
            ]
        });

        player.on('time', function (e) {
            console.log(e);
        })
    </script>
</body>

</html>

SangwonOh avatar Jan 21 '22 04:01 SangwonOh

We are closing the issue due to a long period of inactivity. If further discussion is needed, please open a new issue.

SangwonOh avatar Jan 12 '24 07:01 SangwonOh