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 in Mobile Development by gaurav
• 22,040 points
85 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
0 answers

Open webpage in fullscreen in Safari on iOS

There is a fullscreen mode in Safari ...READ MORE

Nov 22 in Mobile Development by gaurav
• 22,040 points
14 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 in Mobile Development by gaurav
• 22,040 points
20 views
0 votes
0 answers
0 votes
0 answers

Twilio caller name on receive programmable voice call in ios application

I’m using Twilio’s Programmable Voice in one ...READ MORE

Nov 22 in Mobile Development by gaurav
• 22,040 points
25 views
0 votes
0 answers

Streaming video over WiFi and Bluetooth on iOS

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

Nov 23 in Mobile Development by gaurav
• 22,040 points
16 views
0 votes
0 answers

Accurate timing in iOS

I am looking at the 'Metronome' sample ...READ MORE

Nov 8 in Mobile Development by gaurav
• 22,040 points
34 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,800 points
1,842 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,800 points
4,245 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,800 points
422 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