diff --git a/API.md b/API.md index 46053502..ebcd6172 100644 --- a/API.md +++ b/API.md @@ -5,7 +5,6 @@ * [tvOS](#tvos-installation) * [Android](#android-installation) * [Windows](#windows-installation) - * [react-native-dom](#react-native-dom-installation) * [Examples](#examples) * [iOS](#ios-example) * [Android](#android-example) @@ -211,34 +210,6 @@ Add `PackageProviders().Append(winrt::ReactNativeVideoCPP::ReactPackageProvider( Follow the manual linking instuctions for React Native Windows 0.62 above, but substitute _ReactNativeVideoCPP61_ for _ReactNativeVideoCPP_. - - -### react-native-dom installation -
- react-native-dom details - -Make the following additions to the given files manually: - -#### **dom/bootstrap.js** - -Import RCTVideoManager and add it to the list of nativeModules: - -```javascript -import { RNDomInstance } from "react-native-dom"; -import { name as appName } from "../app.json"; -import RCTVideoManager from 'react-native-video/dom/RCTVideoManager'; // Add this - -// Path to RN Bundle Entrypoint ================================================ -const rnBundlePath = "./entry.bundle?platform=dom&dev=true"; - -// React Native DOM Runtime Options ============================================= -const ReactNativeDomOptions = { - enableHotReload: false, - nativeModules: [RCTVideoManager] // Add this -}; -``` -
- ## Examples Run `yarn xbasic install` before running any of the examples. @@ -298,7 +269,7 @@ var styles = StyleSheet.create({ |[backBufferDurationMs](#backBufferDurationMs)| Android | |[bufferConfig](#bufferconfig)|Android| |[contentStartTime](#contentStartTime)| Android | -|[controls](#controls)|Android, iOS, react-native-dom| +|[controls](#controls)|Android, iOS| |[currentPlaybackTime](#currentPlaybackTime)|Android| |[disableFocus](#disableFocus)|Android, iOS| |[disableDisconnectError](#disableDisconnectError)|Android| @@ -309,7 +280,6 @@ var styles = StyleSheet.create({ |[fullscreenOrientation](#fullscreenorientation)|iOS| |[headers](#headers)|Android| |[hideShutterView](#hideshutterview)|Android| -|[id](#id)|react-native-dom| |[ignoreSilentSwitch](#ignoresilentswitch)|iOS| |[maxBitRate](#maxbitrate)|Android, iOS| |[minLoadRetryCount](#minLoadRetryCount)|Android| @@ -447,7 +417,7 @@ The start time in ms for SSAI content. This determines at what time to load the Note on Android, native controls are available by default. If needed, you can also add your controls or use a package like [react-native-video-controls]. -Platforms: Android, iOS, react-native-dom +Platforms: Android, iOS #### disableFocus Determines whether video audio should override background music/audio in Android devices. @@ -548,16 +518,6 @@ Controls whether the ExoPlayer shutter view (black screen while loading) is enab Platforms: Android -#### id -Set the DOM id element so you can use document.getElementById on web platforms. Accepts string values. - -Example: -``` -id="video" -``` - -Platforms: react-native-dom - #### ignoreSilentSwitch Controls the iOS silent switch behavior * **"inherit" (default)** - Use the default AVPlayer behavior diff --git a/dom/RCTVideo.js b/dom/RCTVideo.js deleted file mode 100644 index 77e9dc88..00000000 --- a/dom/RCTVideo.js +++ /dev/null @@ -1,280 +0,0 @@ -// @flow - -/* eslint-env browser */ - -import { RCTView, type RCTBridge } from 'react-native-dom'; -import shaka from 'shaka-player'; - -import resizeModes from './resizeModes'; -import type { VideoSource } from './types'; -import RCTVideoEvent from './RCTVideoEvent'; - -class RCTVideo extends RCTView { - playPromise: Promise = Promise.resolve(); - progressTimer: number; - videoElement: HTMLVideoElement; - - onEnd: boolean = false; - onLoad: boolean = false; - onLoadStart: boolean = false; - onProgress: boolean = false; - - _paused: boolean = false; - _progressUpdateInterval: number = 250.0; - _savedVolume: number = 1.0; - - constructor(bridge: RCTBridge) { - super(bridge); - - 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); - this.onPlay = this.onPlay.bind(this); - this.onProgress = this.onProgress.bind(this); - - this.videoElement = this.initializeVideoElement(); - this.videoElement.addEventListener('ended', this.onEnd); - this.videoElement.addEventListener('loadeddata', this.onLoad); - this.videoElement.addEventListener('canplay', this.onReadyForDisplay); - 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.childContainer.appendChild(this.videoElement); - } - - detachFromView(view: UIView) { - this.videoElement.removeEventListener('ended', this.onEnd); - this.videoElement.removeEventListener('loadeddata', this.onLoad); - this.videoElement.removeEventListener('canplay', this.onReadyForDisplay); - this.videoElement.removeEventListener('loadstart', this.onLoadStart); - this.videoElement.removeEventListener('pause', this.onPause); - this.videoElement.removeEventListener('play', this.onPlay); - - this.stopProgressTimer(); - } - - initializeVideoElement() { - const elem = document.createElement('video'); - - Object.assign(elem.style, { - display: 'block', - position: 'absolute', - top: '0', - left: '0', - width: '100%', - height: '100%', - }); - - return elem; - } - - presentFullscreenPlayer() { - this.videoElement.webkitRequestFullScreen(); - } - - set controls(value: boolean) { - this.videoElement.controls = value; - this.videoElement.style.pointerEvents = value ? 'auto' : ''; - } - - set id(value: string) { - this.videoElement.id = value; - } - - set muted(value: boolean) { - this.videoElement.muted = true; - } - - set paused(value: boolean) { - if (value) { - this.videoElement.pause(); - } else { - this.requestPlay(); - } - this._paused = value; - } - - set progressUpdateInterval(value: number) { - this._progressUpdateInterval = value; - this.stopProgressTimer(); - if (!this._paused) { - this.startProgressTimer(); - } - } - - set rate(value: number) { - this.videoElement.defaultPlaybackRate = value; // playbackRate doesn't work on Chrome - this.videoElement.playbackRate = value; - } - - set repeat(value: boolean) { - this.videoElement.loop = value; - } - - set resizeMode(value: number) { - switch (value) { - case resizeModes.ScaleNone: { - this.videoElement.style.objectFit = 'none'; - break; - } - case resizeModes.ScaleToFill: { - this.videoElement.style.objectFit = 'fill'; - break; - } - case resizeModes.ScaleAspectFit: { - this.videoElement.style.objectFit = 'contain'; - break; - } - case resizeModes.ScaleAspectFill: { - this.videoElement.style.objectFit = 'cover'; - break; - } - } - } - - set seek(value: number) { - this.videoElement.currentTime = value; - } - - set source(value: VideoSource) { - let uri = value.uri; - - if (uri.startsWith('blob:')) { - let blob = this.bridge.blobManager.resolveURL(uri); - if (blob.type === 'text/xml') { - blob = new Blob([blob], { type: 'video/mp4' }); - } - uri = URL.createObjectURL(blob); - } - - if (!shaka.Player.isBrowserSupported()) { // primarily iOS WebKit - this.videoElement.setAttribute('src', uri); - if (!this._paused) { - this.requestPlay(); - } - } else { - this.player.load(uri) - .then(() => { - if (!this._paused) { - this.requestPlay(); - } - }) - .catch(this.onError); - } - } - - set volume(value: number) { - if (value === 0) { - this.muted = true; - } else { - this.videoElement.volume = value; - this.muted = false; - } - } - - onEnd = () => { - this.onProgress(); - this.sendEvent('topVideoEnd', null); - this.stopProgressTimer(); - } - - onError = error => { - console.warn('topVideoError', error); - } - - onLoad = () => { - // height & width are safe with audio, will be 0 - const height = this.videoElement.videoHeight; - const width = this.videoElement.videoWidth; - const payload = { - currentPosition: this.videoElement.currentTime, - duration: this.videoElement.duration, - naturalSize: { - width, - height, - orientation: width >= height ? 'landscape' : 'portrait', - }, - }; - this.sendEvent('topVideoLoad', payload); - } - - onReadyForDisplay = () => { - this.sendEvent('onReadyForDisplay'); - } - - onLoadStart = () => { - const src = this.videoElement.currentSrc; - const payload = { - isNetwork: !src.match(/^https?:\/\/localhost/), // require is served from localhost - uri: this.videoElement.currentSrc, - }; - this.sendEvent('topVideoLoadStart', payload); - } - - onPause = () => { - this.stopProgressTimer(); - } - - onPlay = () => { - this.startProgressTimer(); - } - - onProgress = () => { - const payload = { - currentTime: this.videoElement.currentTime, - seekableDuration: this.videoElement.duration, - }; - 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); - } - - startProgressTimer() { - if (!this.progressTimer && this._progressUpdateInterval) { - this.onProgress(); - this.progressTimer = setInterval(this.onProgress, this._progressUpdateInterval); - } - } - - stopProgressTimer() { - if (this.progressTimer) { - clearInterval(this.progressTimer); - this.progressTimer = null; - } - } -} - -customElements.define('rct-video', RCTVideo); - -export default RCTVideo; diff --git a/dom/RCTVideoEvent.js b/dom/RCTVideoEvent.js deleted file mode 100644 index 4a772cf5..00000000 --- a/dom/RCTVideoEvent.js +++ /dev/null @@ -1,56 +0,0 @@ -// import { RCTEvent } from "react-native-dom"; - -interface RCTEvent { - viewTag: number; - eventName: string; - coalescingKey: number; - - canCoalesce(): boolean; - coalesceWithEvent(event: RCTEvent): RCTEvent; - - moduleDotMethod(): string; - arguments(): Array; - } - -export default class RCTVideoEvent implements RCTEvent { - viewTag: number; - eventName: string; - coalescingKey: number; - - constructor( - eventName: string, - reactTag: number, - coalescingKey: number, - data: ?Object - ) { - this.viewTag = reactTag; - this.eventName = eventName; - this.coalescingKey = coalescingKey; - this.data = data; - } - - canCoalesce(): boolean { - return false; - } - - coalesceWithEvent(event: RCTEvent): RCTEvent { - return; - } - - moduleDotMethod(): string { - return 'RCTEventEmitter.receiveEvent'; - } - - arguments(): Array { - const args = [ - this.viewTag, - this.eventName, - this.data, - ]; - return args; - } - - coalescingKey(): number { - return this.coalescingKey; - } -} diff --git a/dom/RCTVideoManager.js b/dom/RCTVideoManager.js deleted file mode 100644 index efeb4ae0..00000000 --- a/dom/RCTVideoManager.js +++ /dev/null @@ -1,87 +0,0 @@ -// @flow - -import { RCTViewManager } from 'react-native-dom'; - -import RCTVideo from './RCTVideo'; -import resizeModes from './resizeModes'; - -import type { VideoSource } from './types'; - -class RCTVideoManager extends RCTViewManager { - static moduleName = 'RCTVideoManager'; - - view() { - return new RCTVideo(this.bridge); - } - - describeProps() { - return super - .describeProps() - .addBooleanProp('controls', this.setControls) - .addStringProp('id', this.setId) - .addBooleanProp('muted', this.setMuted) - .addBooleanProp('paused', this.setPaused) - .addNumberProp('progressUpdateInterval', this.setProgressUpdateInterval) - .addBooleanProp('rate', this.setRate) - .addBooleanProp('repeat', this.setRepeat) - .addNumberProp('resizeMode', this.setResizeMode) - .addNumberProp('seek', this.setSeek) - .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 - } - - setControls(view: RCTVideo, value: boolean) { - view.controls = value; - } - - setId(view: RCTVideo, value: string) { - view.id = value; - } - - setMuted(view: RCTVideo, value: boolean) { - view.muted = value; - } - - setPaused(view: RCTVideo, value: boolean) { - view.paused = value; - } - - setRate(view: RCTVideo, value: number) { - view.rate = value; - } - - setRepeat(view: RCTVideo, value: boolean) { - view.repeat = value; - } - - setResizeMode(view: RCTVideo, value: number) { - view.resizeMode = value; - } - - setSeek(view: RCTVideo, value: number) { - view.seek = value; - } - - setSource(view: RCTVideo, value: VideoSource) { - view.source = value; - } - - constantsToExport() { - return { ...resizeModes }; - } -} - -export default RCTVideoManager; diff --git a/dom/index.js b/dom/index.js deleted file mode 100644 index e097d5fb..00000000 --- a/dom/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// @flow - -module.exports = require('./RCTVideoManager'); diff --git a/dom/resizeModes.js b/dom/resizeModes.js deleted file mode 100644 index 5f569e0d..00000000 --- a/dom/resizeModes.js +++ /dev/null @@ -1,8 +0,0 @@ -// @flow - -export default { - ScaleNone: 0, - ScaleToFill: 1, - ScaleAspectFit: 2, - ScaleAspectFill: 3, -}; diff --git a/dom/types.js b/dom/types.js deleted file mode 100644 index fe1d1a15..00000000 --- a/dom/types.js +++ /dev/null @@ -1,10 +0,0 @@ -// @flow - -export type VideoSource = { - uri: string, - type: string, - mainVer: number, - patchVer: number, - isNetwork: boolean, - isAsset: boolean, -}; diff --git a/package.json b/package.json index d0170412..9168a673 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,8 @@ "@react-native-community/eslint-config": "^0.0.5", "eslint": "^6.5.1", "react": "16.9.0", - "react-dom": "16.9.0", "react-hot-loader": "^4.12.19", "react-native": "0.61.5", - "react-native-dom": "^0.5.0", "react-native-windows": "^0.61.0-0" }, "dependencies": { @@ -31,7 +29,6 @@ }, "files": [ "android", - "dom", "ios", "windows", "FilterType.js",