bitmovin-player-react-native
Version:
Official React Native bindings for Bitmovin's mobile Player SDKs.
445 lines • 17.4 kB
JavaScript
import { Platform } from 'react-native';
import PlayerModule from './modules/PlayerModule';
import NativeInstance from './nativeInstance';
import { Source } from './source';
import { AnalyticsApi } from './analytics/player';
import { BufferApi } from './bufferApi';
import { Network } from './network';
import { DecoderConfigBridge } from './decoder';
/**
* Loads, controls and renders audio and video content represented through {@link Source}s. A player
* instance can be created via the {@link usePlayer} hook and will idle until one or more {@link Source}s are
* loaded. Once {@link Player.load} or {@link Player.loadSource} is called, the player becomes active and initiates necessary downloads to
* start playback of the loaded source(s).
*
* Can be attached to {@link PlayerView} component in order to use Bitmovin's Player Web UI.
* @see PlayerView
*/
export class Player extends NativeInstance {
/**
* Whether the native `Player` object has been created.
*/
isInitialized = false;
/**
* Whether the native `Player` object has been disposed.
*/
isDestroyed = false;
/**
* Currently active source, or `null` if none is active.
*/
source;
/**
* The `AnalyticsApi` for interactions regarding the `Player`'s analytics.
*
* `undefined` if the player was created without analytics support.
*/
analytics = undefined;
/**
* The {@link BufferApi} for interactions regarding the buffer.
*/
buffer = new BufferApi(this.nativeId);
network;
decoderConfig;
/**
* Allocates the native `Player` instance and its resources natively.
*/
initialize = async () => {
if (!this.isInitialized) {
if (this.config?.networkConfig) {
this.network = new Network(this.config.networkConfig);
await this.network.initialize();
}
await this.maybeInitDecoderConfig();
const analyticsConfig = this.config?.analyticsConfig;
if (analyticsConfig) {
await PlayerModule.initializeWithAnalyticsConfig(this.nativeId, analyticsConfig, this.config, this.network?.nativeId, this.decoderConfig?.nativeId);
this.analytics = new AnalyticsApi(this.nativeId);
}
else {
await PlayerModule.initializeWithConfig(this.nativeId, this.config, this.network?.nativeId, this.decoderConfig?.nativeId);
}
this.isInitialized = true;
}
return Promise.resolve();
};
/**
* Destroys the native `Player` and releases all of its allocated resources.
*/
destroy = () => {
if (!this.isDestroyed) {
PlayerModule.destroy(this.nativeId);
this.source?.destroy();
this.network?.destroy();
this.decoderConfig?.destroy();
this.isDestroyed = true;
}
};
/**
* Loads a new {@link Source} from `sourceConfig` into the player.
*/
load = (sourceConfig) => {
this.loadSource(new Source(sourceConfig));
};
/**
* Loads the downloaded content from {@link OfflineContentManager} into the player.
*/
loadOfflineContent = (offlineContentManager, options) => {
PlayerModule.loadOfflineContent(this.nativeId, offlineContentManager.nativeId, options);
};
/**
* Loads the given {@link Source} into the player.
*/
loadSource = (source) => {
this.source = source;
source.initialize().then(() => {
PlayerModule.loadSource(this.nativeId, source.nativeId);
});
};
/**
* Unloads all {@link Source}s from the player.
*/
unload = () => {
PlayerModule.unload(this.nativeId);
};
/**
* Starts or resumes playback after being paused. Has no effect if the player is already playing.
*/
play = () => {
PlayerModule.play(this.nativeId);
};
/**
* Pauses the video if it is playing. Has no effect if the player is already paused.
*/
pause = () => {
PlayerModule.pause(this.nativeId);
};
/**
* Seeks to the given playback time specified by the parameter `time` in seconds. Must not be
* greater than the total duration of the video. Has no effect when watching a live stream since
* seeking is not possible.
*
* @param time - The time to seek to in seconds.
*/
seek = (time) => {
PlayerModule.seek(this.nativeId, time);
};
/**
* Shifts the time to the given `offset` in seconds from the live edge. The resulting offset has to be within the
* timeShift window as specified by `maxTimeShift` (which is a negative value) and 0. When the provided `offset` is
* positive, it will be interpreted as a UNIX timestamp in seconds and converted to fit into the timeShift window.
* When the provided `offset` is negative, but lower than `maxTimeShift`, then it will be clamped to `maxTimeShift`.
* Has no effect for VoD.
*
* Has no effect if no sources are loaded.
*
* @param offset - Target offset from the live edge in seconds.
*/
timeShift = (offset) => {
PlayerModule.timeShift(this.nativeId, offset);
};
/**
* Mutes the player if an audio track is available. Has no effect if the player is already muted.
*/
mute = () => {
PlayerModule.mute(this.nativeId);
};
/**
* Unmutes the player if it is muted. Has no effect if the player is already unmuted.
*/
unmute = () => {
PlayerModule.unmute(this.nativeId);
};
/**
* Sets the player's volume between 0 (silent) and 100 (max volume).
*
* @param volume - The volume level to set.
*/
setVolume = (volume) => {
PlayerModule.setVolume(this.nativeId, volume);
};
/**
* @returns The player's current volume level.
*/
getVolume = async () => {
return (await PlayerModule.getVolume(this.nativeId)) ?? 0;
};
/**
* @returns The current playback time in seconds.
*
* For VoD streams the returned time ranges between 0 and the duration of the asset.
*
* For live streams it can be specified if an absolute UNIX timestamp or a value
* relative to the playback start should be returned.
*
* @param mode - The time mode to specify: an absolute UNIX timestamp ('absolute') or relative time ('relative').
*/
getCurrentTime = async (mode = 'absolute') => {
return (await PlayerModule.currentTime(this.nativeId, mode)) ?? 0;
};
/**
* @returns The total duration in seconds of the current video or INFINITY if it’s a live stream.
*/
getDuration = async () => {
return (await PlayerModule.duration(this.nativeId)) ?? 0;
};
/**
* @returns `true` if the player is muted.
*/
isMuted = async () => {
return (await PlayerModule.isMuted(this.nativeId)) ?? false;
};
/**
* @returns `true` if the player is currently playing, i.e. has started and is not paused.
*/
isPlaying = async () => {
return (await PlayerModule.isPlaying(this.nativeId)) ?? false;
};
/**
* @returns `true` if the player has started playback but it's currently paused.
*/
isPaused = async () => {
return (await PlayerModule.isPaused(this.nativeId)) ?? false;
};
/**
* @returns `true` if the displayed video is a live stream.
*/
isLive = async () => {
return (await PlayerModule.isLive(this.nativeId)) ?? false;
};
/**
* @remarks Only available for iOS devices.
* @returns `true` when media is played externally using AirPlay.
*/
isAirPlayActive = async () => {
if (Platform.OS === 'android') {
console.warn(`[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.`);
return false;
}
return (await PlayerModule.isAirPlayActive(this.nativeId)) ?? false;
};
/**
* @remarks Only available for iOS devices.
* @returns `true` when AirPlay is available.
*/
isAirPlayAvailable = async () => {
if (Platform.OS === 'android') {
console.warn(`[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.`);
return false;
}
return (await PlayerModule.isAirPlayAvailable(this.nativeId)) ?? false;
};
/**
* @returns The currently selected audio track or `null`.
*/
getAudioTrack = async () => {
return PlayerModule.getAudioTrack(this.nativeId);
};
/**
* @returns An array containing {@link AudioTrack} objects for all available audio tracks.
*/
getAvailableAudioTracks = async () => {
return PlayerModule.getAvailableAudioTracks(this.nativeId);
};
/**
* Sets the audio track to the ID specified by trackIdentifier. A list can be retrieved by calling getAvailableAudioTracks.
*
* @param trackIdentifier - The {@link AudioTrack.identifier} to be set.
*/
setAudioTrack = async (trackIdentifier) => {
return PlayerModule.setAudioTrack(this.nativeId, trackIdentifier);
};
/**
* @returns The currently selected {@link SubtitleTrack} or `null`.
*/
getSubtitleTrack = async () => {
return PlayerModule.getSubtitleTrack(this.nativeId);
};
/**
* @returns An array containing SubtitleTrack objects for all available subtitle tracks.
*/
getAvailableSubtitles = async () => {
return PlayerModule.getAvailableSubtitles(this.nativeId);
};
/**
* Sets the subtitle track to the ID specified by trackIdentifier. A list can be retrieved by calling getAvailableSubtitles.
*
* @param trackIdentifier - The {@link SubtitleTrack.identifier} to be set.
*/
setSubtitleTrack = async (trackIdentifier) => {
return PlayerModule.setSubtitleTrack(this.nativeId, trackIdentifier ?? '');
};
/**
* Dynamically schedules the {@link AdItem} for playback.
* Has no effect if there is no active playback session.
*
* @param adItem - Ad to be scheduled for playback.
*
* @remarks Platform: iOS, Android
*/
scheduleAd = (adItem) => {
PlayerModule.scheduleAd(this.nativeId, adItem);
};
/**
* Skips the current ad.
* Has no effect if the current ad is not skippable or if no ad is being played back.
*
* @remarks Platform: iOS, Android
*/
skipAd = () => {
PlayerModule.skipAd(this.nativeId);
};
/**
* @returns `true` while an ad is being played back or when main content playback has been paused for ad playback.
* @remarks Platform: iOS, Android
*/
isAd = async () => {
return (await PlayerModule.isAd(this.nativeId)) ?? false;
};
/**
* The current time shift of the live stream in seconds. This value is always 0 if the active {@link Source} is not a
* live stream or no sources are loaded.
*/
getTimeShift = async () => {
return (await PlayerModule.getTimeShift(this.nativeId)) ?? 0;
};
/**
* The limit in seconds for time shifting. This value is either negative or 0 and it is always 0 if the active
* {@link Source} is not a live stream or no sources are loaded.
*/
getMaxTimeShift = async () => {
return (await PlayerModule.getMaxTimeShift(this.nativeId)) ?? 0;
};
/**
* Sets the upper bitrate boundary for video qualities. All qualities with a bitrate
* that is higher than this threshold will not be eligible for automatic quality selection.
*
* Can be set to `null` for no limitation.
*/
setMaxSelectableBitrate = (bitrate) => {
PlayerModule.setMaxSelectableBitrate(this.nativeId, bitrate || -1);
};
/**
* @returns a {@link Thumbnail} for the specified playback time for the currently active source if available.
* Supported thumbnail formats are:
* - `WebVtt` configured via {@link SourceConfig.thumbnailTrack}, on all supported platforms
* - HLS `Image Media Playlist` in the multivariant playlist, Android-only
* - DASH `Image Adaptation Set` as specified in DASH-IF IOP, Android-only
* If a `WebVtt` thumbnail track is provided, any potential in-manifest thumbnails are ignored on Android.
*
* @param time - The time in seconds for which to retrieve the thumbnail.
*/
getThumbnail = async (time) => {
return PlayerModule.getThumbnail(this.nativeId, time);
};
/**
* Whether casting to a cast-compatible remote device is available. {@link CastAvailableEvent} signals when
* casting becomes available.
*
* @remarks Platform: iOS, Android
*/
isCastAvailable = async () => {
return (await PlayerModule.isCastAvailable(this.nativeId)) ?? false;
};
/**
* Whether video is currently being casted to a remote device and not played locally.
*
* @remarks Platform: iOS, Android
*/
isCasting = async () => {
return (await PlayerModule.isCasting(this.nativeId)) ?? false;
};
/**
* Initiates casting the current video to a cast-compatible remote device. The user has to choose to which device it
* should be sent.
*
* @remarks Platform: iOS, Android
*/
castVideo = () => {
PlayerModule.castVideo(this.nativeId);
};
/**
* Stops casting the current video. Has no effect if {@link Player.isCasting} is `false`.
*
* @remarks Platform: iOS, Android
*/
castStop = () => {
PlayerModule.castStop(this.nativeId);
};
/**
* Returns the currently selected video quality.
* @returns The currently selected video quality.
*/
getVideoQuality = async () => {
return PlayerModule.getVideoQuality(this.nativeId);
};
/**
* Returns an array containing all available video qualities the player can adapt between.
* @returns An array containing all available video qualities the player can adapt between.
*/
getAvailableVideoQualities = async () => {
return PlayerModule.getAvailableVideoQualities(this.nativeId);
};
/**
* Sets the video quality.
* @remarks Platform: Android
*
* @param qualityId value obtained from {@link VideoQuality}'s `id` property, which can be obtained via `Player.getAvailableVideoQualities()` to select a specific quality. To use automatic quality selection, 'auto' can be passed here.
*/
setVideoQuality = (qualityId) => {
if (Platform.OS !== 'android') {
console.warn(`[Player ${this.nativeId}] Method setVideoQuality is not available for iOS and tvOS devices. Only Android devices.`);
return;
}
PlayerModule.setVideoQuality(this.nativeId, qualityId);
};
/**
* Sets the playback speed of the player. Fast forward, slow motion and reverse playback are supported.
* @remarks
* Platform: iOS, tvOS
*
* - Slow motion is indicated by values between `0` and `1`.
* - Fast forward by values greater than `1`.
* - Slow reverse is used by values between `0` and `-1`, and fast reverse is used by values less than `-1`. iOS and tvOS only.
* - Negative values are ignored during Casting and on Android.
* - During reverse playback the playback will continue until the beginning of the active source is
* reached. When reaching the beginning of the source, playback will be paused and the playback
* speed will be reset to its default value of `1`. No {@link PlaybackFinishedEvent} will be
* emitted in this case.
*
* @param playbackSpeed - The playback speed to set.
*/
setPlaybackSpeed = (playbackSpeed) => {
PlayerModule.setPlaybackSpeed(this.nativeId, playbackSpeed);
};
/**
* @see {@link setPlaybackSpeed} for details on which values playback speed can assume.
* @returns The player's current playback speed.
*/
getPlaybackSpeed = async () => {
return (await PlayerModule.getPlaybackSpeed(this.nativeId)) ?? 0;
};
/**
* Checks the possibility to play the media at specified playback speed.
* @param playbackSpeed - The playback speed to check.
* @returns `true` if it's possible to play the media at the specified playback speed, otherwise `false`. On Android it always returns `undefined`.
* @remarks Platform: iOS, tvOS
*/
canPlayAtPlaybackSpeed = async (playbackSpeed) => {
if (Platform.OS === 'android') {
console.warn(`[Player ${this.nativeId}] Method canPlayAtPlaybackSpeed is not available for Android. Only iOS and tvOS devices.`);
return undefined;
}
return ((await PlayerModule.canPlayAtPlaybackSpeed(this.nativeId, playbackSpeed)) ?? false);
};
maybeInitDecoderConfig = () => {
if (this.config?.playbackConfig?.decoderConfig == null) {
return;
}
if (Platform.OS === 'ios') {
return;
}
this.decoderConfig = new DecoderConfigBridge(this.config.playbackConfig.decoderConfig);
this.decoderConfig.initialize();
};
}
//# sourceMappingURL=player.js.map