Commit f0e0e555 authored by Hampton Maxwell's avatar Hampton Maxwell
Browse files

Add id prop & autoplay handling, support DASH & HLS via Shaka Player

parent 864da19d
Loading
Loading
Loading
Loading
+45 −21
Changes for dom/RCTVideo.js: 45 added lines, 21 removed lines.
Original line number Diff line number Diff line
// @flow

import { RCTEvent, RCTView, type RCTBridge } from "react-native-dom";
import shaka from "shaka-player";

import resizeModes from "./resizeModes";
import type { VideoSource } from "./types";
@@ -25,6 +26,8 @@ class RCTVideo extends RCTView {

    this.eventDispatcher = bridge.getModuleByName("EventDispatcher");

    shaka.polyfill.installAll();

    this.onEnd = this.onEnd.bind(this);
    this.onLoad = this.onLoad.bind(this);
    this.onLoadStart = this.onLoadStart.bind(this);
@@ -37,11 +40,11 @@ class RCTVideo extends RCTView {
    this.videoElement.addEventListener("loadstart", this.onLoadStart);
    this.videoElement.addEventListener("pause", this.onPause);
    this.videoElement.addEventListener("play", this.onPlay);
    this.player = new shaka.Player(this.videoElement);

    this.muted = false;
    this.rate = 1.0;
    this.volume = 1.0;
    this.videoElement.autoplay = true;
    this.childContainer.appendChild(this.videoElement);
  }

@@ -71,36 +74,28 @@ class RCTVideo extends RCTView {
  }

  presentFullscreenPlayer() {
    console.log("V PF");
    this.videoElement.webkitRequestFullScreen();
  }

  set controls(value: boolean) {
    if (value) {
      this.videoElement.controls = true;
      this.videoElement.style.pointerEvents = "auto";
    } else {
      this.videoElement.controls = false;
      this.videoElement.style.pointerEvents = "";
    this.videoElement.controls = value;
    this.videoElement.style.pointerEvents = value ? "auto" : "";
  }

  set id(value: string) {
    this.videoElement.id = value;
  }

  set muted(value: boolean) {
    if (value) {
    this.videoElement.muted = true;
    } else {
      this.videoElement.muted = false;
    }
  }

  set paused(value: boolean) {
    this.playPromise.then(() => {
    if (value) {
      this.videoElement.pause();
    } else {
        this.playPromise = this.videoElement.play();
      this.requestPlay();
    }
    });
    this._paused = value;
  }

@@ -118,11 +113,7 @@ class RCTVideo extends RCTView {
  }

  set repeat(value: boolean) {
    if (value) {
      this.videoElement.setAttribute("loop", "true");
    } else {
      this.videoElement.removeAttribute("loop");
    }
    this.videoElement.loop = value;
  }

  set resizeMode(value: number) {
@@ -161,9 +152,19 @@ class RCTVideo extends RCTView {
      uri = URL.createObjectURL(blob);
    }

    if (!shaka.Player.isBrowserSupported()) { // primarily iOS WebKit
      this.videoElement.setAttribute("src", uri);
      if (!this._paused) {
      this.playPromise = this.videoElement.play();
        this.requestPlay();
      }
    } else {
      this.player.load(uri)
        .then(() => {
          if (!this._paused) {
            this.requestPlay();
          }
        })
        .catch(this.onError);
    }
  }

@@ -182,6 +183,10 @@ class RCTVideo extends RCTView {
    this.stopProgressTimer();    
  }

  onError = error => {
    console.warn("topVideoError", error);
  }

  onLoad = () => {
    // height & width are safe with audio, will be 0
    const height = this.videoElement.videoHeight;
@@ -223,6 +228,25 @@ class RCTVideo extends RCTView {
    this.sendEvent("topVideoProgress", payload);
  }

  onRejectedAutoplay = () => {
    this.sendEvent("topVideoRejectedAutoplay", null);
  }

  requestPlay() {
    const playPromise = this.videoElement.play();
    if (playPromise) {
      playPromise
        .then(() => {})
        .catch(e => {
          /* This is likely one of:
           * name: NotAllowedError - autoplay is not supported
           * name: NotSupportedError - format is not supported
           */
          this.onError({ code: e.name, message: e.message });
        });
    }
  }

  sendEvent(eventName, payload) {
    const event = new RCTVideoEvent(eventName, this.reactTag, 0, payload);
    this.eventDispatcher.sendEvent(event);
+10 −0
Changes for dom/RCTVideoManager.js: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ class RCTVideoManager extends RCTViewManager {
    return super
      .describeProps()
      .addBooleanProp("controls", this.setControls)
      .addStringProp("id", this.setId)
      .addBooleanProp("muted", this.setMuted)
      .addBooleanProp("paused", this.setPaused)
      .addNumberProp("progressUpdateInterval", this.setProgressUpdateInterval)
@@ -28,11 +29,16 @@ class RCTVideoManager extends RCTViewManager {
      .addObjectProp("src", this.setSource)
      .addNumberProp("volume", this.setVolume)
      .addDirectEvent("onVideoEnd")
      .addDirectEvent("onVideoError")
      .addDirectEvent("onVideoLoad")
      .addDirectEvent("onVideoLoadStart")
      .addDirectEvent("onVideoProgress");
  }

  dismissFullscreenPlayer() {
    // not currently working
  }

  presentFullscreenPlayer() {
    // not currently working
  }
@@ -41,6 +47,10 @@ class RCTVideoManager extends RCTViewManager {
    view.controls = value;
  }

  setId(view: RCTVideo, value: string) {
    view.id = value;
  }

  setMuted(view: RCTVideo, value: boolean) {
    view.muted = value;
  }
+2 −1
Changes for package.json: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@
    },
    "dependencies": {
        "keymirror": "0.1.1",
        "prop-types": "^15.5.10"
        "prop-types": "^15.5.10",
	"shaka-player": "2.4.4"
    },
    "scripts": {
        "test": "node_modules/.bin/eslint *.js"