function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import React, { Component } from "react";
import { View, StyleSheet, Dimensions } from "react-native";
import YoutubePlayer, { getYoutubeMeta } from "react-native-youtube-iframe";
import { Vimeo } from "react-native-vimeo-iframe";
import { WebView } from "react-native-webview";
import { Video, ResizeMode } from "expo-av";
import { Spinner } from "./Spinner";
const SCREEN_HEIGHT = Dimensions.get("window").height;
const SCREEN_WIDTH = Dimensions.get("window").width;
const EXPO_VIDEO_PROPS = {
  rate: 1,
  isMuted: false,
  volume: 1
};
const RETRY_RECOVER = 30000;
const RETRY_LOADING = 10000;
class MediaPlayer extends Component {
  constructor(props) {
    super(props);
    _defineProperty(this, "componentDidMount", async () => {
      await this.setupForPlaying();
    });
    _defineProperty(this, "componentWillUnmount", () => {
      if (this.checkStreamLoaded) clearInterval(this.checkStreamLoaded);
    });
    _defineProperty(this, "getYoutubeVideoId", url => {
      url = url.replace(/(>|<)/gi, "").split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
      if (url[2] !== undefined) {
        const ids = url[2].split(/[^0-9a-z_\-]/i);
        return ids[0];
      } else {
        return "";
      }
    });
    _defineProperty(this, "getVimeoId", url => {
      const result = url.match(/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:[a-zA-Z0-9_\-]+)?/i);
      return result[1];
    });
    _defineProperty(this, "setupForPlaying", async () => {
      // Extract live stream info
      const {
        source,
        useVideoPlayer
      } = this.props;
      const isUrlLink = source && source.startsWith("http");
      const isYoutube = source && (source.includes("youtube.com/watch?v=") || source.includes("youtu.be/"));
      const isVimeo = source && source.includes("vimeo.com/");
      let heightFactor = 0;
      if (isYoutube) {
        const metadata = await getYoutubeMeta(this.getYoutubeVideoId(source));
        heightFactor = metadata.height / metadata.width;
      } else if (useVideoPlayer) {
        heightFactor = 0;
      } else {
        heightFactor = 0.565;
      }
      this.setState({
        isUrlLink,
        isYoutube,
        isVimeo,
        playbackLoaded: isYoutube || isVimeo,
        heightFactor,
        readyToRender: true
      });
    });
    _defineProperty(this, "getStreamPlaybackUrl", () => {
      // return 'https://stream.mux.com/Ym4nKktRpGuZNBBBlzhxpyRwZLpvMlPRchcu01x6Ur600.m3u8';
      return `https://stream.mux.com/${this.props.playbackId}.m3u8`;
    });
    _defineProperty(this, "checkReloadStream", (wait = RETRY_LOADING, force = false) => {
      if (!force && this.retryLoading) return;
      console.log(`Check loading in ${wait} milliseconds...`);
      this.retryLoading = true;
      setTimeout(async () => {
        const {
          playbackLoaded,
          playbackBuffering
        } = this.state;
        try {
          if (playbackLoaded === false || playbackBuffering === true) {
            console.log("Reloading started");
            await this.videoPlayer.loadAsync({
              uri: this.getStreamPlaybackUrl(),
              overrideFileExtensionAndroid: "m3u8"
            }, EXPO_VIDEO_PROPS, false);
          } else {
            console.log("Already loaded - not reloading");
          }
          this.retryLoading = false;
        } catch {}
      }, wait);
    });
    _defineProperty(this, "isLandscape", deviceRotation => {
      const {
        beta,
        gamma
      } = deviceRotation;
      const absGamma = Math.abs(gamma);
      const absBeta = Math.abs(beta);
      const isGammaNegative = Math.sign(gamma) === -1;
      if (absGamma <= 0.04 && absBeta <= 0.24) {
        //Portrait mode, on a flat surface.
        return false;
      } else if ((absGamma <= 1.0 || absGamma >= 2.3) && absBeta >= 0.5) {
        //General Portrait mode, accounting for forward and back tilt on the top of the phone.
        return false;
      } else {
        if (isGammaNegative) {
          //Landscape mode with the top of the phone to the left.
          return true;
        } else {
          //Landscape mode with the top of the phone to the right.
          return true;
        }
      }
    });
    _defineProperty(this, "onMotionChange", async changeEvent => {
      const deviceRotation = changeEvent.rotation;
      const deviceOrientation = changeEvent.orientation;
      const isLandscape = this.isLandscape(deviceRotation);
      this.orientationQueue.push(isLandscape);
      if (this.orientationQueue.length > 2) this.orientationQueue = this.orientationQueue.slice(-2);
      // console.log('onMotionChange - orientationQueue', this.orientationQueue);
      if (isLandscape !== this.state.isLandscape && isLandscape === (Math.abs(deviceOrientation) === 90) && this.orientationQueue.every(i => i === isLandscape)) {
        this.setState({
          isLandscape
        }, () => {
          // console.log('isLandscape', this.state.isLandscape);
          if (this.props.orientationChanged) this.props.orientationChanged(this.state.isLandscape);
        });
      }
    });
    _defineProperty(this, "onStreamLoadStart", () => {
      console.log("Stream load started");
      this.checkStreamLoaded = setInterval(() => {
        const {
          playbackLoaded
        } = this.state;
        if (playbackLoaded === false) {
          console.log("Stream loading failed unexpectedly");
          this.checkReloadStream(1000, true);
        } else {
          clearInterval(this.checkStreamLoaded);
        }
      }, RETRY_RECOVER);
    });
    _defineProperty(this, "onStreamLoaded", status => {
      console.log(`Stream loaded - isLoaded:${status.isLoaded}, isBuffering:${status.isBuffering}, isPlaying:${status.isPlaying}`);
    });
    _defineProperty(this, "onStreamError", error => {
      console.log("Stream error", error);
    });
    _defineProperty(this, "onStreamStatusUpdate", status => {
      this.setState({
        playbackLoaded: status.isLoaded,
        playbackBuffering: status.isBuffering,
        playbackPlaying: status.isPlaying
      }, () => {
        const {
          playbackLoaded,
          playbackBuffering,
          playbackPlaying,
          shouldPlay
        } = this.state;
        // console.log(`Status updated - isLoaded:${playbackLoaded}, isBuffering:${playbackBuffering}, isPlaying:${playbackPlaying}`);
        if (playbackLoaded === false && playbackBuffering === undefined && playbackPlaying === undefined) {
          this.checkReloadStream();
        } else if (playbackLoaded === true && playbackBuffering === true) {
          this.checkReloadStream(RETRY_RECOVER);
        }
      });
    });
    _defineProperty(this, "onYoutubeError", e => {
      // console.log('onYoutubeError', e);
      this.setState({
        forceWebview: true
      });
    });
    _defineProperty(this, "onYoutubeReady", () => {
      // console.log('onYoutubeReady');
    });
    _defineProperty(this, "onVideoPlayStatusUpdate", status => {
      // console.log('onVideoPlayStatusUpdate', status);
    });
    _defineProperty(this, "onVideoPlayError", error => {
      if (error && error.type === "NonFatal") {
        return;
      }
      // console.log('onVideoPlayError', error);
      this.setState({
        forceWebview: true
      });
    });
    _defineProperty(this, "getYoutubePlayer", (youtubeId, width, height, autoPlay) => /*#__PURE__*/React.createElement(YoutubePlayer, {
      ref: ref => this.youtubePlayer = ref,
      height: height,
      width: width,
      videoId: youtubeId,
      play: autoPlay
      // onChangeState={event => console.log('onChangeState', event)}
      ,
      onReady: this.onYoutubeReady,
      onError: this.onYoutubeError
      // onPlaybackQualityChange={q => console.log('onPlaybackQualityChange', q)}
      ,
      volume: 50,
      playbackRate: 1,
      playerParams: {
        cc_lang_pref: "us",
        showClosedCaptions: true
      }
    }));
    _defineProperty(this, "getVimeoPlayer", (vimeoId, width, height, autoPlay) => /*#__PURE__*/React.createElement(View, {
      style: {
        width,
        height
      }
    }, /*#__PURE__*/React.createElement(Vimeo, {
      style: {
        marginLeft: -8,
        marginRight: -5
      },
      videoId: vimeoId
      // onReady={() => console.log('Video is ready')}
      // onPlay={() => console.log('Video is playing')}
      // onPlayProgress={data => console.log('Video progress data:', data)}
      // onFinish={() => console.log('Video is finished')}
      ,
      loop: false,
      autoPlay: autoPlay,
      controls: true,
      speed: true,
      time: "0m0s"
    })));
    _defineProperty(this, "getWebviewPlayer", (embedUrl, width, height) => /*#__PURE__*/React.createElement(WebView, {
      startInLoadingState: true,
      javaScriptEnabled: true,
      scrollEnabled: false,
      automaticallyAdjustContentInsets: false,
      mediaPlaybackRequiresUserAction: true,
      style: [styles.webView, {
        width,
        height
      }],
      source: {
        uri: embedUrl
      }
    }));
    _defineProperty(this, "getStreamPlayer", (embedUrl, width, height, autoPlay) => /*#__PURE__*/React.createElement(Video, _extends({
      ref: vp => {
        this.videoPlayer = vp;
      },
      source: {
        uri: embedUrl
      }
    }, EXPO_VIDEO_PROPS, {
      shouldPlay: autoPlay,
      resizeMode: ResizeMode.CONTAIN,
      useNativeControls: true,
      style: {
        width,
        height
      },
      onLoadStart: this.onStreamLoadStart,
      onLoad: this.onStreamLoaded,
      onError: this.onStreamError,
      onPlaybackStatusUpdate: this.onStreamStatusUpdate
    })));
    this.state = {
      deviceOrientation: null,
      isLandscape: false,
      isUrlLink: true,
      isYoutube: false,
      isVimeo: false,
      forceWebview: false,
      heightFactor: 0,
      playbackLoaded: false,
      playbackBuffering: false,
      playbackPlaying: false,
      readyToRender: false
    };
    this.youtubePlayer = null;
    this.videoPlayer = null;
    this.checkStreamLoaded = null;
    this.retryLoading = false;
    this.orientationQueue = [];
  }
  // getVideoPlayer = (embedUrl, width, height, autoPlay) => (
  //   <VideoPlayer
  //     videoProps={{
  //       shouldPlay: autoPlay,
  //       resizeMode: Video.RESIZE_MODE_CONTAIN,
  //       source: { uri: embedUrl },
  //     }}
  //     showFullscreenButton={false}
  //     errorCallback={this.onVideoPlayError}
  //     playbackCallback={this.onVideoPlayStatusUpdate}
  //     height={height}
  //     width={width}
  //   />
  // );

  render() {
    let width, height;
    const {
      playbackId,
      source,
      autoPlay,
      useVideoPlayer
    } = this.props;
    const {
      readyToRender,
      isLandscape,
      heightFactor,
      isUrlLink,
      isYoutube,
      isVimeo,
      forceWebview,
      playbackLoaded,
      playbackBuffering
    } = this.state;
    if (!readyToRender) return null;
    if (isLandscape) {
      width = SCREEN_HEIGHT;
      height = SCREEN_WIDTH;
    } else {
      width = SCREEN_WIDTH;
      height = heightFactor ? SCREEN_WIDTH * heightFactor : SCREEN_HEIGHT;
    }
    let embedUrl, player, showLoading;
    if (!forceWebview) {
      if (isYoutube) {
        const youtubeId = this.getYoutubeVideoId(source);
        embedUrl = youtubeId ? `https://www.youtube.com/embed/${youtubeId}` : source;
        // console.log('getYoutubePlayer', youtubeId, width, height, autoPlay);
        player = this.getYoutubePlayer(youtubeId, width, height, autoPlay);
      } else if (isVimeo) {
        const vimeoId = this.getVimeoId(source);
        embedUrl = source;
        // console.log('getVimeoPlayer', vimeoId, width, height, autoPlay);
        player = this.getVimeoPlayer(vimeoId, width, height, autoPlay);
      } else if (playbackId) {
        embedUrl = this.getStreamPlaybackUrl();
        // console.log('getStreamPlayer', embedUrl, width, height, autoPlay);
        player = this.getStreamPlayer(embedUrl, width, height, autoPlay);
        showLoading = true;
      } else if (useVideoPlayer) {
        embedUrl = source;
        // console.log('getVideoPlayer', embedUrl, width, height, autoPlay);
        player = this.getStreamPlayer(embedUrl, width, height, autoPlay);
      }
    }
    if (!player && isUrlLink) {
      embedUrl = source;
      console.log("getWebviewPlayer", embedUrl, width, height);
      player = this.getWebviewPlayer(embedUrl, width, height);
    }

    // console.log({
    //   Streaming: embedUrl,
    //   Landscape: isLandscape,
    //   Loaded: playbackLoaded,
    //   Buffering: playbackBuffering,
    //   LoadingIndicator: showLoading,
    //   Width: width,
    //   Height: height,
    //   HeightFactor: heightFactor,
    //   isYoutube,
    //   isVimeo,
    //   playbackId,
    //   useVideoPlayer,
    // });
    return /*#__PURE__*/React.createElement(View, {
      style: styles.container
    }, player, showLoading && (!playbackLoaded || playbackBuffering) && /*#__PURE__*/React.createElement(View, {
      style: styles.loadingContainer
    }, /*#__PURE__*/React.createElement(Spinner, {
      color: "#fff"
    })));
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#000",
    alignItems: "center",
    justifyContent: "center"
  },
  webView: {
    flex: 1
  },
  loadingContainer: {
    position: "absolute",
    top: 50,
    left: 0,
    right: 0,
    bottom: 50,
    justifyContent: "center",
    alignItems: "center"
  }
});
export default MediaPlayer;
//# sourceMappingURL=MediaPlayer.js.map