Search code examples
javascripthtmlhtml5-video

HTML5 Video click event for closed captions?


I'm creating a custom video player using the <video> html5 tag.

Currently I'm accessing the video.pause() and video.play() methods to control playback. There are further controls within the controls attribute such as "Closed Captions".

I can access the object like so: video.textTracks[0].mode however, what I would like is to add a click event to toggle the captions displaying on or off.

Is this possible? Looking through docs under available methods it doesn't seem so: https://www.w3schools.com/tags/ref_av_dom.asp

I'm currently doing this with the pause and play methods available on the video HTMLVideoElement like so:

 const handleMouseEnter: React.MouseEventHandler<HTMLVideoElement> = () => {
    setIsHover(true);
  };

  const handleMouseLeave: React.MouseEventHandler<HTMLVideoElement> = () => {
    setIsHover(false);
  };

  const handleClick: React.MouseEventHandler<HTMLVideoElement> = (event) => {
    const video = event.target;

    if (video && video instanceof HTMLVideoElement) {
      console.log('video :>> ', video.textTracks[0].mode.toString());
      if (video.paused) {
        video.play();
        setPlay(true);
      } else {
        video.pause();
        setPlay(false);
      }
    }
  };

Useage:

<video
  className={`cursor-pointer ${className}`}
  onClick={handleClick}
  onMouseEnter={handleMouseEnter}
  onMouseLeave={handleMouseLeave}
  controlsList={'nodownload noremoteplayback'}
  crossOrigin="anonymous"
>
  <track src={captions} kind="captions" srcLang="en" label="English" />
  <source src={url} type="video/mp4" />
</video>

Solution

  • So I found an way to do it - hope this helps someone in future.

    const handleCaptions: React.MouseEventHandler<HTMLImageElement> = () => {
        const video = document.querySelector('video');
    
        if (video instanceof HTMLVideoElement && video.textTracks[0].mode === 'disabled') {
          setPlayerCaptions('showing');
          video.textTracks[0].mode = 'showing';
        } else if (video instanceof HTMLVideoElement && video.textTracks[0].mode === 'showing') {
          setPlayerCaptions('disabled');
          video.textTracks[0].mode = 'disabled';
        }
      };
    

    Usage:

    <Image
      src={CaptionsSVG}
      width={170}
      height={170}
      alt="Captions"
      className="caption absolute bottom-0 right-0 z-10 cursor-pointer"
      priority={true}
      onClick={handleCaptions}
    />