Can t play video on iOS in Safari NotAllowedError

0 votes

When I click a play button on an iPhone in Safari, I get the following error:

NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

I searched on the internet and it seems that this issue has been around for a long time but there is no clear solution to it.

Here is my code. It works everywhere except iOS Safari.

import { Box } from '@chakra-ui/react';
import { useTranslation } from 'libs/i18next';
import React, { useEffect, useRef, useState } from 'react';
import { PauseIcon, PlayIcon } from 'theme/icons';
import { visuallyHiddenCss } from 'utils/style-utils';

import {
  buttonHoverArea,
  playButtonCss,
  playIconStyles,
  videoContainerCss,
  videoCss,
} from './Video.styles';

export interface Video extends React.HTMLProps<HTMLVideoElement> {
  src: string;
  noVideoText?: string;
  className?: string;
  isEnabled?: boolean;
  coversParent?: boolean;
  handlePlayPress?: (videoPlaying: boolean) => void;
}

/**
 * Default HTML5 video player with a play button and a preview thumbnail image.
 */
export const Video = ({
  src,
  noVideoText,
  className,
  loop = false,
  autoPlay = false, // AutoPlay doesn't work currently
  isEnabled = true,
  coversParent = false,
  handlePlayPress,
  ...props
}: Video): React.ReactElement => {
  const [t] = useTranslation(['common']);
  const videoRef = useRef<HTMLVideoElement>(null);
  const buttonRef = useRef<HTMLButtonElement>(null);
  // use videoStarted state to hide the play button once it has been started
  const [videoPlaying, setVideoPlaying] = useState<boolean>(false);

  const pauseVideo = () => {
    setVideoPlaying(false);
  };

  const toggleVideo = () => {
    if (handlePlayPress) {
      handlePlayPress(!videoPlaying);
    }
    setVideoPlaying(!videoPlaying);
  };

  const defaultProps: Partial<Video> = {
    width: '100%',
    height: '100%',
    preload: 'none',
    onClick: pauseVideo,
    tabIndex: -1,
  };
  const videoProps = Object.assign(defaultProps, props);

  useEffect(() => {
    if (videoRef.current && props.muted) {
      // force muted prop
      // https://github.com/facebook/react/issues/10389#issuecomment-605689475
      videoRef.current.setAttribute('muted', '');
      videoRef.current.defaultMuted = true;
    }
  }, [props.muted, videoRef]);

  useEffect(() => {
    if (isEnabled && videoPlaying) {
      videoRef.current?.play();
      buttonRef.current?.blur();
      videoRef.current?.focus();
    } else {
      videoRef.current?.pause();
    }
  }, [isEnabled, videoPlaying, videoRef]);

  const PlayPauseIcon = videoPlaying ? PauseIcon : PlayIcon;

  return (
    <Box
      css={[
        videoContainerCss.base,
        coversParent ? videoContainerCss.cover : undefined,
      ]}
      className={className}
    >
      {/* eslint-disable-next-line jsx-a11y/media-has-caption */}
      <video
        ref={videoRef}
        css={videoCss}
        {...videoProps}
        autoPlay={autoPlay}
        loop={loop}
      >
        <source src={src} type={'video/mp4'} />
        {noVideoText}
      </video>
      {isEnabled && (
        <div
          css={[buttonHoverArea.base, videoPlaying && buttonHoverArea.playing]}
        >
          <button
            type="button"
            ref={buttonRef}
            css={playButtonCss}
            onClick={toggleVideo}
            // prevent hidden elements from being focused
          >
            <span css={visuallyHiddenCss}>
              {videoPlaying ? t('common:video.pause') : t('common:video.play')}
            </span>
            <PlayPauseIcon
              css={!videoPlaying && playIconStyles}
              boxSize={'6rem'}
              aria-hidden
            />
          </button>
        </div>
      )}
    </Box>
  );
};

Nov 8, 2022 in Mobile Development by gaurav
• 23,260 points
1,158 views

No answer to this question. Be the first to respond.

Your answer

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.

Related Questions In Mobile Development

0 votes
1 answer

Open webpage in fullscreen in Safari on iOS

Not all platforms are equal. iOS Safari doesn't ...READ MORE

answered Nov 25, 2022 in Mobile Development by gaurav
• 23,260 points
502 views
0 votes
0 answers

Default Ringtone on a VOIP app in iOS

I'm trying to find a way to ...READ MORE

Nov 16, 2022 in Mobile Development by gaurav
• 23,260 points
475 views
0 votes
1 answer

Flutter project in iOS emulator takes forever to run, but its worked on Android emulator

Try flutter clean and flutter build ios ...READ MORE

answered Nov 18, 2022 in Mobile Development by gaurav
• 23,260 points
416 views
0 votes
1 answer

Twilio caller name on receive programmable voice call in ios application

Twilio developer evangelist here. In order to get ...READ MORE

answered Dec 15, 2022 in Mobile Development by gaurav
• 23,260 points
676 views
0 votes
0 answers

Streaming video over WiFi and Bluetooth on iOS

This question is going to be quite ...READ MORE

Nov 23, 2022 in Mobile Development by gaurav
• 23,260 points
408 views
0 votes
0 answers

Streaming video over WiFi and Bluetooth on iOS

This question is going to be quite ...READ MORE

Nov 30, 2022 in Mobile Development by gaurav
• 23,260 points
253 views
0 votes
1 answer

Error:Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag

Hello @kartik, It is happening because any where ...READ MORE

answered Jun 4, 2020 in Angular by Niroj
• 82,880 points
2,242 views
0 votes
1 answer

Error:setState doesn't update the state immediately

Hello @kartik, The method setState() takes a callback. And ...READ MORE

answered Jun 4, 2020 in Angular by Niroj
• 82,880 points
4,913 views
0 votes
1 answer

From php returning JSON to JavaScript

Hii @kartik, You can use Simple JSON for PHP. ...READ MORE

answered Jun 5, 2020 in Java-Script by Niroj
• 82,880 points
800 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP