Kamran Ali
Kamran Ali

Reputation: 61

Video Autoplay and Long Press Functionality for React Video Component: Works on Desktop but Not on Mobile

I'm working on a React component where I need to implement functionality similar to Instagram's video playback behavior. The requirements are as follows:

When the video comes into the viewport, it should automatically start playing. When the user scrolls up and the video leaves the viewport, it should pause. When the user performs a long press (500ms) on the video, it should toggle between play and pause. On a regular click, the video should toggle mute. I've implemented the following code, which works as expected on desktop browsers. However, on mobile browsers, the video does not autoplay when it intersects with the user's viewport.

Here's my current implementation:

import React, { useEffect, useRef, useState } from 'react';

const VideoComponent = ({ postData }) => {
  const videoRef = useRef(null);
  const longPressTimeout = useRef(null);
  const [isMuted, setIsMuted] = useState(true);
  const [isLongPress, setIsLongPress] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          videoRef.current?.play();
        } else {
          videoRef.current?.pause();
        }
      },
      { threshold: 0.75 }
    );

    const videoElement = videoRef.current;
    if (videoElement) {
      observer.observe(videoElement);
    }

    return () => {
      if (videoElement) {
        observer.unobserve(videoElement);
      }
    };
  }, []);

  const handleLongPressStart = () => {
    longPressTimeout.current = setTimeout(() => {
      setIsLongPress(true);
      videoRef.current?.pause();
    }, 500); // Long press duration (500ms)
  };

  const handleLongPressEnd = () => {
    clearTimeout(longPressTimeout.current);
    if (isLongPress) {
      videoRef.current?.play();
      videoRef.current.muted = !isMuted; // Unmute the video immediately
      setIsMuted(!isMuted); // Update the state to reflect the unmuted status
      setIsLongPress(false);
    }
  };

  const handleMuteClick = () => {
    if (!isLongPress) {
      const newMuteState = !isMuted;
      videoRef.current.muted = newMuteState;
      setIsMuted(newMuteState);
    }
  };

  return (
    <video
      ref={videoRef}
      src={postData?.video}
      className="w-full h-96"
      muted={isMuted}
      onClick={handleMuteClick}
      onMouseDown={handleLongPressStart}
      onMouseUp={handleLongPressEnd}
      onMouseLeave={handleLongPressEnd}
      onTouchStart={handleLongPressStart}
      onTouchEnd={handleLongPressEnd}
      playsInline
      preload="auto"
    />
  );
};

export default VideoComponent;

On desktop, the video plays and pauses correctly when it enters or leaves the viewport, and the long press functionality works perfectly.

On mobile, the video does not autoplay when it intersects with the viewport.

1.Why does the video not autoplay on mobile browsers when it intersects with the viewport? 2.Are there any specific mobile browser settings or restrictions that I need to consider? 3.How can I modify my code to ensure the video autoplay works on mobile devices as well?

Any help or pointers to resolve this issue would be greatly appreciated. Thank you!

Upvotes: 0

Views: 52

Answers (0)

Related Questions