This time I have finished this simple webcast, the next step is to use myself, if there are improvements or bugs and so on and then record.

Today I’m going to focus on solving the full-screen problem in Safari. As I said last time, based on the previous code, it would be fine in Chrome, but in Safari it would just have a little bit of video in the middle, although it would be full screen.

And the reason why this is happening is because I added width and height to the full screen div, so in Safari full screen and if you look at the full screen is the last node that’s currently bound to the full screen div, this is the virtual node, and if you look at the current node, if it’s 100% then it fills the entire screen, Otherwise, the given width and height. Chrome has the current node in full screen, so there’s no problem.

Code section:

<div className={`liveThe ${liveClassName} `} >// Previously bound to this node, this node outside can control the width and height<div className={'video-container'} ref={divRef}>// Now bind to this node<video controls={false} ref={videoRef} className={'video'} >
          {`Your browser is too old which doesn't support HTML5 video.`}
        </video>.Copy the code

Just as it is now.

And then there’s the video streaming problem that I was talking about, turning off the video stream, which I think is a nonsense requirement, because first of all it doesn’t make sense to turn off the video stream for live streaming, and then you have to think about how you can turn it off again. I think in both cases, first do not need to recover, that also means the user once you click on close video streaming can refresh the page or by other means to open the video, that have no meaning of live, so I do is when the user exit the current page, or for my components, component is unloaded when I close the video stream. In the second case, if you can open it in the same way after closing it, why not pause it? Of course, it is possible that it is just an illusion with the user to close the video stream, so I clicked on the video stream to pause the operation, and the video was closed interface, when I clicked again to delete this line of text, and the interface appeared again.

Effect:When clicked again it will restore the video.

This time the player was very simple, but I still spent a lot of time, I haven’t done web development for a long time, CSS is forgotten, and DOM node related to forget badly.

I feel that I can’t go back for Chinese New Year this year. I will spend it in Beijing. The sorrow.

Here is the code for this component. Again, I want to make it clear that I prefer to keep a diary, that is, keep a diary so that I can read it for myself. It takes a certain amount of technology to start a blog. If someone accidentally saw it, if they still see it, if they find something wrong with what I said, or something that you don’t see, you can tell me about it.

import React, {useCallback, useEffect, useRef, useState} from 'react';
import flvJs from 'flv.js';
import {Slider} from 'antd';
import './styles.less';
import bofang from '.. /.. /common/assets/bofang.svg';
import quanping from '.. /.. /common/assets/quanping.svg';
import shexiangtou from '.. /.. /common/assets/shexiangtou.svg';
import yangshengqi from '.. /.. /common/assets/yangshengqi.svg';
import zanting from '.. /.. /common/assets/zanting.svg';

interface DIVTypeHTML extends HTMLDivElement {
  mozRequestFullScreen: () = > void;
  webkitRequestFullscreen: () = > void;
  msRequestFullscreen: () = > void;
  isFullscreen: boolean;
}

interfaceLiveProps { liveClassName? :string;
  url: string;
  videoSourceText: string;
}

function Live({liveClassName, url, videoSourceText}: LiveProps) {
  const [isPlay, setIsPlay] = useState(false);
  const [isShowAudio, setIsShowAudio] = useState(false);
  const flvRef = useRef<flvJs.Player>();
  const videoRef = useRef<HTMLVideoElement>(null);
  const divRef = useRef<DIVTypeHTML>(null);
  const [closeVideoText, setCloseVideo] = useState('hide');
  useEffect(() = > {
    if (flvJs.isSupported()) {
      flvRef.current = flvJs.createPlayer({
        type: 'flv'.isLive: true.cors: true.hasVideo: true,
        url,
      });
      if(videoRef.current) { flvRef.current.attachMediaElement(videoRef.current); flvRef.current.load(); }}return () = >{ flvRef.current? .pause(); flvRef.current? .unload(); flvRef.current? .detachMediaElement(); flvRef.current? .destroy(); flvRef.current =undefined;
      setIsPlay(false);
    };
  }, [url]);
  const requestFullscreen = useCallback((document: DIVTypeHTML) = > {
    if (document.requestFullscreen) {
      document.requestFullscreen();
    } else if (document.mozRequestFullScreen) {
      document.mozRequestFullScreen();
    } else if (document.webkitRequestFullscreen) {
      document.webkitRequestFullscreen();
    } else if (document.msRequestFullscreen) {
      document.msRequestFullscreen(); }} []);const exitFullscreen = useCallback(() = > {
    const document: any = window.document;
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen(); }} []);const onClickPlay = useCallback(() = > {
    if (flvRef.current) {
      if (isPlay) {
        flvRef.current.pause();
      } else{ flvRef.current.play(); } setIsPlay(! isPlay); } }, [isPlay]);const onClickAudio = useCallback(() = > {
    setIsShowAudio((isSHow) = > !isSHow);
  }, []);
  const onClickFullscreen = useCallback(() = > {
    const document = divRef.current;
    if (!document) {
      return;
    }
    if (document.isFullscreen) {
      exitFullscreen();
    } else {
      requestFullscreen(document);
    }
    document.isFullscreen = !document.isFullscreen;
  }, [exitFullscreen, requestFullscreen]);
  const onChange = useCallback((value: number) = > {
    if (videoRef.current) {
      videoRef.current.volume = value / 100; }} []);const onVideoClick = useCallback(() = > {
    setCloseVideo((close) = > {
      if (close === 'hide') {
        if (flvRef.current) {
          flvRef.current.pause();
          setIsPlay(false);
        }
        return 'show';
      } else {
        return 'hide'; }}); } []);return (
    <div className={`liveThe ${liveClassName} `} >
      <div className={'video-container'} ref={divRef}>
        <video controls={false} ref={videoRef} className={'video'} >
          {`Your browser is too old which doesn't support HTML5 video.`}
        </video>
        <div className={`video-text video-text-The ${closeVideoText} `} >
          <span>The current video is closed</span>
        </div>
        <div className={'control'} >{/* Control play and pause */}<div className={'img-container'} >
            <img
              src={isPlay ? zanting : bofang}
              className={'img'}
              onClick={onClickPlay}
            />
          </div>{/* control whether the video stream is turned off */}<div className={'img-container'} >
            <img src={shexiangtou} onClick={onVideoClick} className={'img'} / >
          </div>{/* control sound */}<div
            className={'img-container audio-container'}
            onClick={onClickAudio}>
            <img src={yangshengqi} className={'img'} / >
            <div className={`audioThe ${isShowAudio ? 'show' : 'hide'} `} >
              <Slider
                defaultValue={100}
                min={0}
                max={100}
                vertical
                tipFormatter={null}
                onChange={onChange}
              />
            </div>
          </div>{/* what is the current video panorama video /* /} {videoSourceText? (<div className={'img-container'} >
              <span className={'text-detail'} >{videoSourceText}</span>
            </div>) : null} {/* Whether to display in full screen */}<div className={'img-container'} onClick={onClickFullscreen}>
            <img src={quanping} className={'img'} / >
          </div>
        </div>
      </div>
    </div>
  );
}

export default Live;
Copy the code