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,126 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
474 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
449 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
368 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
636 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
371 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
207 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,218 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,879 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
762 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