Add id prop & autoplay handling, support DASH & HLS via Shaka Player
This commit is contained in:
parent
864da19d41
commit
f0e0e555dd
@ -1,6 +1,7 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { RCTEvent, RCTView, type RCTBridge } from "react-native-dom";
|
import { RCTEvent, RCTView, type RCTBridge } from "react-native-dom";
|
||||||
|
import shaka from "shaka-player";
|
||||||
|
|
||||||
import resizeModes from "./resizeModes";
|
import resizeModes from "./resizeModes";
|
||||||
import type { VideoSource } from "./types";
|
import type { VideoSource } from "./types";
|
||||||
@ -25,6 +26,8 @@ class RCTVideo extends RCTView {
|
|||||||
|
|
||||||
this.eventDispatcher = bridge.getModuleByName("EventDispatcher");
|
this.eventDispatcher = bridge.getModuleByName("EventDispatcher");
|
||||||
|
|
||||||
|
shaka.polyfill.installAll();
|
||||||
|
|
||||||
this.onEnd = this.onEnd.bind(this);
|
this.onEnd = this.onEnd.bind(this);
|
||||||
this.onLoad = this.onLoad.bind(this);
|
this.onLoad = this.onLoad.bind(this);
|
||||||
this.onLoadStart = this.onLoadStart.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("loadstart", this.onLoadStart);
|
||||||
this.videoElement.addEventListener("pause", this.onPause);
|
this.videoElement.addEventListener("pause", this.onPause);
|
||||||
this.videoElement.addEventListener("play", this.onPlay);
|
this.videoElement.addEventListener("play", this.onPlay);
|
||||||
|
this.player = new shaka.Player(this.videoElement);
|
||||||
|
|
||||||
this.muted = false;
|
this.muted = false;
|
||||||
this.rate = 1.0;
|
this.rate = 1.0;
|
||||||
this.volume = 1.0;
|
this.volume = 1.0;
|
||||||
this.videoElement.autoplay = true;
|
|
||||||
this.childContainer.appendChild(this.videoElement);
|
this.childContainer.appendChild(this.videoElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,36 +74,28 @@ class RCTVideo extends RCTView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
presentFullscreenPlayer() {
|
presentFullscreenPlayer() {
|
||||||
console.log("V PF");
|
|
||||||
this.videoElement.webkitRequestFullScreen();
|
this.videoElement.webkitRequestFullScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
set controls(value: boolean) {
|
set controls(value: boolean) {
|
||||||
if (value) {
|
this.videoElement.controls = value;
|
||||||
this.videoElement.controls = true;
|
this.videoElement.style.pointerEvents = value ? "auto" : "";
|
||||||
this.videoElement.style.pointerEvents = "auto";
|
|
||||||
} else {
|
|
||||||
this.videoElement.controls = false;
|
|
||||||
this.videoElement.style.pointerEvents = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set id(value: string) {
|
||||||
|
this.videoElement.id = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
set muted(value: boolean) {
|
set muted(value: boolean) {
|
||||||
if (value) {
|
|
||||||
this.videoElement.muted = true;
|
this.videoElement.muted = true;
|
||||||
} else {
|
|
||||||
this.videoElement.muted = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set paused(value: boolean) {
|
set paused(value: boolean) {
|
||||||
this.playPromise.then(() => {
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.videoElement.pause();
|
this.videoElement.pause();
|
||||||
} else {
|
} else {
|
||||||
this.playPromise = this.videoElement.play();
|
this.requestPlay();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
this._paused = value;
|
this._paused = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,11 +113,7 @@ class RCTVideo extends RCTView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set repeat(value: boolean) {
|
set repeat(value: boolean) {
|
||||||
if (value) {
|
this.videoElement.loop = value;
|
||||||
this.videoElement.setAttribute("loop", "true");
|
|
||||||
} else {
|
|
||||||
this.videoElement.removeAttribute("loop");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set resizeMode(value: number) {
|
set resizeMode(value: number) {
|
||||||
@ -161,9 +152,19 @@ class RCTVideo extends RCTView {
|
|||||||
uri = URL.createObjectURL(blob);
|
uri = URL.createObjectURL(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!shaka.Player.isBrowserSupported()) { // primarily iOS WebKit
|
||||||
this.videoElement.setAttribute("src", uri);
|
this.videoElement.setAttribute("src", uri);
|
||||||
if (!this._paused) {
|
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();
|
this.stopProgressTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onError = error => {
|
||||||
|
console.warn("topVideoError", error);
|
||||||
|
}
|
||||||
|
|
||||||
onLoad = () => {
|
onLoad = () => {
|
||||||
// height & width are safe with audio, will be 0
|
// height & width are safe with audio, will be 0
|
||||||
const height = this.videoElement.videoHeight;
|
const height = this.videoElement.videoHeight;
|
||||||
@ -223,6 +228,25 @@ class RCTVideo extends RCTView {
|
|||||||
this.sendEvent("topVideoProgress", payload);
|
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) {
|
sendEvent(eventName, payload) {
|
||||||
const event = new RCTVideoEvent(eventName, this.reactTag, 0, payload);
|
const event = new RCTVideoEvent(eventName, this.reactTag, 0, payload);
|
||||||
this.eventDispatcher.sendEvent(event);
|
this.eventDispatcher.sendEvent(event);
|
||||||
|
@ -18,6 +18,7 @@ class RCTVideoManager extends RCTViewManager {
|
|||||||
return super
|
return super
|
||||||
.describeProps()
|
.describeProps()
|
||||||
.addBooleanProp("controls", this.setControls)
|
.addBooleanProp("controls", this.setControls)
|
||||||
|
.addStringProp("id", this.setId)
|
||||||
.addBooleanProp("muted", this.setMuted)
|
.addBooleanProp("muted", this.setMuted)
|
||||||
.addBooleanProp("paused", this.setPaused)
|
.addBooleanProp("paused", this.setPaused)
|
||||||
.addNumberProp("progressUpdateInterval", this.setProgressUpdateInterval)
|
.addNumberProp("progressUpdateInterval", this.setProgressUpdateInterval)
|
||||||
@ -28,11 +29,16 @@ class RCTVideoManager extends RCTViewManager {
|
|||||||
.addObjectProp("src", this.setSource)
|
.addObjectProp("src", this.setSource)
|
||||||
.addNumberProp("volume", this.setVolume)
|
.addNumberProp("volume", this.setVolume)
|
||||||
.addDirectEvent("onVideoEnd")
|
.addDirectEvent("onVideoEnd")
|
||||||
|
.addDirectEvent("onVideoError")
|
||||||
.addDirectEvent("onVideoLoad")
|
.addDirectEvent("onVideoLoad")
|
||||||
.addDirectEvent("onVideoLoadStart")
|
.addDirectEvent("onVideoLoadStart")
|
||||||
.addDirectEvent("onVideoProgress");
|
.addDirectEvent("onVideoProgress");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dismissFullscreenPlayer() {
|
||||||
|
// not currently working
|
||||||
|
}
|
||||||
|
|
||||||
presentFullscreenPlayer() {
|
presentFullscreenPlayer() {
|
||||||
// not currently working
|
// not currently working
|
||||||
}
|
}
|
||||||
@ -41,6 +47,10 @@ class RCTVideoManager extends RCTViewManager {
|
|||||||
view.controls = value;
|
view.controls = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setId(view: RCTVideo, value: string) {
|
||||||
|
view.id = value;
|
||||||
|
}
|
||||||
|
|
||||||
setMuted(view: RCTVideo, value: boolean) {
|
setMuted(view: RCTVideo, value: boolean) {
|
||||||
view.muted = value;
|
view.muted = value;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"keymirror": "0.1.1",
|
"keymirror": "0.1.1",
|
||||||
"prop-types": "^15.5.10"
|
"prop-types": "^15.5.10",
|
||||||
|
"shaka-player": "2.4.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node_modules/.bin/eslint *.js"
|
"test": "node_modules/.bin/eslint *.js"
|
||||||
|
Loading…
Reference in New Issue
Block a user