@xymatic/react-native-green-video
v2.0.94
Published
React-native wrapper for green-video SDK
Downloads
1,236
Readme
react-native-green-video
React Native wrapper for the GreenVideo SDK.
[TOC]
Installation
Yarn
Run this command:
yarn add @xymatic/react-native-green-videonpm
Run this command:
npm install @xymatic/react-native-green-videoiOS
In your ios/Podfile raise your minimum supported iOS version to 14.0 by changing this line:
platform :ios, min_ios_version_supportedto:
platform :ios, 14.0Run pod install --repo-update in your ios subdirectory.
Android
Generally, Android should work out of the box without any changes needed. If you are getting an error about kotlin version mismatch, set a matching version inside android/build.gradle file in buildscript > ext for example:
kotlinVersion = "2.1.0"Upgrading
Note that yarn will save the commit SHA in yarn.lock. In order to get the latest version from the main branch, you
will have to delete the lockfile, remove the entry, or re-install the package.
Usage
Example
Make sure to set your own embedId and licenseKey.
import * as React from 'react';
import {
Dimensions,
Button,
ActivityIndicator,
StyleSheet,
View,
} from 'react-native';
import {GreenVideo, type TimeUpdate} from '@xymatic/react-native-green-video';
import {
defaultEmbedId,
defaultContentId,
defaultLicenseKey,
} from './src/constants';
const Example = () => {
const [isReady, setIsReady] = React.useState(false);
const [isPlaying, setIsPlaying] = React.useState(false);
const [timeInfo, setTimeInfo] = React.useState({
currentTime: 0,
duration: 0,
});
const testRef = React.useRef<GreenVideo>(null);
const play = () => {
testRef?.current?.play();
};
const pause = () => {
testRef?.current?.pause();
};
const seek = (position: number) => {
testRef?.current?.seek(Math.round(position));
};
const onPlay = () => {
setIsPlaying(true);
};
const onPause = () => {
setIsPlaying(false);
};
const onReady = () => {
setIsReady(true);
};
const onTimeUpdate = (event: TimeUpdate) => {
const {currentTime, duration} = event;
setTimeInfo({
currentTime,
duration,
});
};
const renderControls = () => {
if (isReady) {
return (
<View style={styles.buttonContainer}>
<Button
onPress={() => seek(timeInfo.currentTime - 15)}
title="-15s"
/>
<Button disabled={isPlaying} onPress={play} title="Play" />
<Button disabled={!isPlaying} onPress={pause} title="Pause" />
<Button
onPress={() => seek(timeInfo.currentTime + 15)}
title="+15s"
/>
</View>
);
}
return <ActivityIndicator />;
};
return (
<View style={styles.container}>
<GreenVideo
ref={testRef}
licenseKey={defaultLicenseKey}
embedId={defaultEmbedId}
contentId={defaultContentId}
onPlay={onPlay}
onPause={onPause}
onReady={onReady}
onTimeUpdate={onTimeUpdate}
onSeek={time => console.log(time)}
onMilestoneReached={milestone => console.log(milestone)}
style={styles.video}
/>
{renderControls()}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
alignItems: 'center',
justifyContent: 'center',
},
video: {
marginHorizontal: 8,
height: Dimensions.get('window').height / 2,
width: Dimensions.get('window').width - 64,
},
buttonContainer: {
height: 96,
flexDirection: 'row',
gap: 16,
},
});
export default Example;Props
| Prop | Required | Default | Type | Description |
| :-------------------------- | :------: | :-----: | :-------: | :---------------------------------------------------------------- |
| licenseKey | yes | none | string | Your Green Video license key |
| embedId | yes | none | string | An embed id |
| mixId | no | none | string | A mix id. Overrides the value in the configuration |
| contentId | no | none | string | A content id |
| adTagUrl | no | none | string | Url for getting ad tags |
| environment | no | prod | 'staging' \| 'prod' | Which environment to use |
| adsDisallowed | no | false | boolean | Disable ads |
| debug | no | false | boolean | Enables detailed logging |
Functions
| Function | Arguments | Description |
| :-------------------------- | :--------------: | :---------------------------------------------------------------- |
| play | none | Start playback |
| pause | none | Stop playback |
| seek | (position: number) | Seek to position in Video in s |
| seekForward | (time: number) | Seek forward from current position |
| seekBackward | (time: number) | Seek backward from current position |
| mute | none | Mute audio |
| unmute | none | Unmute audio |
| enterFullscreen | none | Enter fullscreen video |
| exitFullscreen | none | Exit fullscreen video |
| showUi | none | Show native player controls |
| hideUi | none | Hide native player controls |
| startContent | (clickToPlay: boolean, withSound: boolean) | Start a content as user and force sound |
| startNextContent | none | Start next content |
| startPreviousContent | none | Start previous content |
| setSnapFrame | (left: number, top: number, width: number, height: number) | Set the on-screen snap frame (usually driven by SnapFrameOverlay) |
| clearSnapFrame | none | Stop snap tracking and leave snap mode |
Events
| Events | arguments | Description |
| :-------------------------- | :--------------: | :---------------------------------------------------------------- |
| onPlay | none | Playback has started |
| onPause | none | Playback has paused |
| onMute | none | Audio was muted |
| onUnmute | none | Audio was unmuted |
| onEnterFullscreen | none | Player has entered fullscreen |
| onExitFullscreen | none | Player has left fullscreen |
| onShowUi | none | Native controls have become visible |
| onHideUi | none | Native controls have disappeared |
| onReplay | (count: number, context: string) | Replay has started; count starts at 1 |
| onSeek | none | Seek to position / forward / backward completed |
| onTimeUpdate | (timeUpdate: { currentTime: number, duration: number } | Playback time changed |
| onMilestoneReached | (milestone: 'ms5' \| 'ms25' \| 'ms50' \| 'ms75' \| 'ms100') | Playback milestone reached |
| onEnterSnapMode | (dockPosition: string \| undefined, context: string) | Player docked into snap (floating) mode |
| onExitSnapMode | (context: string) | Player left snap (floating) mode and returned inline |
Snapping (floating mini-player)
Snap mode keeps a video playing in a small floating "mini-player" docked to a
corner of the screen once the inline player scrolls out of view — similar to
YouTube's minimize-to-corner behaviour. When the player scrolls back into view
it returns inline. All of the detection, animation and playback continuity is
handled natively by the GreenVideo SDK; on the React Native side you only need
to add a SnapFrameOverlay.
SnapFrameOverlay renders as an absolute-fill overlay. Place it as the last
child of the container that fills the viewport your scrollable player lives in,
and bind it to the same ref you attach to the <GreenVideo> you want to dock.
It measures the on-screen "snap frame" and streams it to the player, and reveals
the docked corner slot while the player is snapped.
import * as React from 'react';
import { ScrollView, View } from 'react-native';
import {
GreenVideo,
type GreenVideoRef,
SnapFrameOverlay,
} from '@xymatic/react-native-green-video';
const SnapExample = () => {
const playerRef = React.useRef<GreenVideoRef>(null);
return (
<View style={{ flex: 1 }}>
<ScrollView>
{/* …content… */}
<GreenVideo
ref={playerRef}
licenseKey={defaultLicenseKey}
embedId={defaultEmbedId}
contentId={defaultContentId}
style={{ width: '100%', aspectRatio: 16 / 9 }}
/>
{/* …content… */}
</ScrollView>
{/* Enables the floating mini-player. Bound to the same player ref. */}
<SnapFrameOverlay player={playerRef} cornerWidth={256} cornerHeight={144} />
</View>
);
};SnapFrameOverlay props
| Prop | Required | Default | Type | Description |
| :-------------- | :------: | :----------------: | :-----------------: | :----------------------------------------------------------------- |
| player | yes | none | RefObject<GreenVideoRef \| null> | Ref of the <GreenVideo> to dock |
| padding | no | 10 | number | Inset of the snap frame from the overlay's edges |
| showBorder | no | false | boolean | Draw a debug border around the snap frame |
| borderColor | no | 'red' | string | Debug border color |
| borderWidth | no | 4 | number | Debug border width (also insets the docked slot) |
| cornerInset | no | 8 | number | Extra inset of the docked slot from the frame corner |
| cornerAlignment | no | 'bottom-right' | GreenVideoDockPosition | Corner the docked slot is pinned to, unless the SDK reports a different dockPosition at runtime (the top-center* variants render centered) |
| cornerWidth | no | 200 | number | Docked slot width |
| cornerHeight | no | cornerWidth·9/16 | number | Docked slot height |
See example/src/screens/SnapCase.tsx for a full working screen.
