@nativeframe/react-native-native-frame
Version:
React native package for streaming
307 lines (300 loc) • 9.51 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NativeFramePlayer = void 0;
var _react = require("react");
var _ManifestPlayerEvents = require("../native-events/ManifestPlayerEvents.js");
var _videoClientCore = require("@video/video-client-core");
var _api = require("@video/video-client-core/lib/api");
// import { rnLogger } from '@videorn/video-client-reactnative';
// import { MediaStream } from '@videomobile/react-native-webrtc';
const ALL_PLAYERS = [{
id: 'webrtc'
}, {
id: 'native-hls'
}];
const formatMappings = {
'webrtc': 'webrtc',
'native-hls': 'mp4-hls'
};
class NativeFramePlayer extends _react.Component {
TAG = 'NativeFramePlayer';
events = new _ManifestPlayerEvents.ManifestPlayerEvents(this);
player = null;
mediaStream = null;
availableQualities = [];
initPlayerTimeout = null;
constructor(props) {
super(props);
const {
token,
videoClientOptions,
players,
autoplay,
muted
} = props;
this.videoClient = new _videoClientCore.VideoClient({
token: token,
...videoClientOptions
});
const sanitizedPlayers = players?.reduce((accumulator, playerId) => {
return [...accumulator, {
id: playerId
}];
}, []);
this.players = sanitizedPlayers ?? ALL_PLAYERS;
this.state = {
format: undefined,
driver: null,
source: null,
availableQualities: [],
paused: !(autoplay || videoClientOptions?.autoPlay || videoClientOptions?.playerOptions?.autoPlay),
muted: (muted || videoClientOptions?.playerOptions?.muted) ?? false
};
this.videoClient.on('error', error => {
if (error.code !== 'manifest-error') {
// rnLogger.error('Video client error.', error);
this.events.onError(JSON.stringify(error));
}
});
this.initManifestPlayer();
this.events.subscribeEvents();
}
componentDidUpdate(prevProps) {
if (this.props.manifestUrl !== prevProps.manifestUrl) {
if (this.initPlayerTimeout) clearTimeout(this.initPlayerTimeout);
this.initPlayerTimeout = setTimeout(() => {
this.onRequestReloadPlayer();
}, this.props.debounceInitTime ?? 500);
}
}
initManifestPlayer = () => {
if (!this.props.manifestUrl) return;
const options = {
players: this.players,
preferredScoreLevel: this.props.preferredScoreLevel,
autoPlay: !this.state.paused,
muted: this.state.muted
};
try {
const player = this.videoClient.requestPlayer(this.props.manifestUrl, options);
this.player = player;
player.on('error', error => {
// rnLogger.error('Player emits error.', error);
const isManifestError = error.message.includes('MANIFEST_FORBIDDEN') || error.message.includes('MANIFEST_UNAUTHORIZED');
if (isManifestError) {
this.events.onManifestUnauthorized(JSON.stringify(error));
} else {
this.events.onError(JSON.stringify(error));
}
});
player.on('driver', driver => {
this.mediaStream = null;
this.setState({
format: formatMappings[driver],
driver: driver
});
this.events.onDriverChange(driver);
});
player.on('manifest', manifest => {
if (manifest.code === 200) {
this.events.onManifest(JSON.stringify(manifest));
} else if (manifest.code === 404) {
this.events.onStreamOffline(JSON.stringify(manifest));
}
});
player.provider?.on('source', manifest => {
if (!this.state.format) return;
const format = manifest.formats?.[this.state.format];
if ((0, _api.isGenericFormat)(format) && format.manifest) {
const currentQualityLayer = this.player?.currentPlayer?.currentQuality?.layer;
let source;
if (currentQualityLayer != null && currentQualityLayer.id !== '' && this.player?.preferredLevel) {
source = currentQualityLayer.id.toString();
} else {
source = format.manifest;
}
if (source === this.state.source) return;
this.setState({
source
});
this.events.onManifestSourceChange(source);
}
});
player.on('joinedCall', ({
call
}) => {
if (!call) return;
call.on('streamAdded', event => {
event.stream.on('source', _stream => {
// const tracks = stream.getTracks();
if (this.mediaStream) {
// tracks.forEach((track) => {
// this.mediaStream?.removeTrack(track as any);
// });
}
// Crete new media stream to see quality changes
this.mediaStream = new MediaStream();
// tracks.forEach((track) => {
// if (player.localAudioMuted && track.kind === 'audio')
// track.enabled = false;
// if (player.localVideoPaused) track.enabled = false;
// this.mediaStream?.addTrack(track as any);
// });
const mediaStreamURL = this.mediaStream.toURL();
this.setState({
source: mediaStreamURL
});
this.events.onManifestSourceChange(mediaStreamURL);
});
});
});
player.on('availableQualities', availableQualities => {
const qualities = availableQualities.map(({
level
}) => level);
this.availableQualities = qualities;
this.setState({
availableQualities: qualities
});
this.events.onAvailableQualities(qualities);
});
player.on('disposed', () => {
this.events.onDisposed();
});
player.on('playerAccessDenied', ({
message
}) => {
this.events.onAccessDenied(message);
});
player.on('peerAtCapacity', () => {
this.events.onPeerAtCapacity();
});
player.provider?.on('videoPaused', paused => {
if (this.state.format === 'webrtc' && this.mediaStream) {
// const tracks = this.mediaStream.getTracks();
// tracks.forEach((track) => {
// track.enabled = !paused;
// });
}
if (paused) {
this.events.onVideoPaused();
} else {
this.events.onVideoPlay();
}
this.setState({
paused
});
});
player.provider?.on('audioMuted', muted => {
if (this.state.format === 'webrtc' && this.mediaStream) {
// const tracks = this.mediaStream.getTracks();
// tracks.forEach((track) => {
// if (track.kind === 'audio') {
// track.enabled = !muted;
// }
// });
}
this.events.onMute(muted);
});
} catch (error) {
// rnLogger.error('Error requesting player.', error);
this.events.onError('Error requesting player.' + error + '');
}
};
onRequestTimeupdate = () => {
if (!this.player) return;
this.player.emit('timeupdate');
};
onRequestVideoPause = () => {
if (!this.player) return;
this.player.localVideoPaused = true;
if (this.state.format === 'webrtc' && this.mediaStream) {
// const tracks = this.mediaStream.getTracks();
// tracks.forEach((track) => {
// track.enabled = false;
// });
}
this.setState({
paused: true
});
this.events.onVideoPaused();
};
onRequestVideoPlay = () => {
if (!this.player) return;
this.player.localVideoPaused = false;
if (this.state.format === 'webrtc' && this.mediaStream) {
// const tracks = this.mediaStream.getTracks();
// tracks.forEach((track) => {
// track.enabled = true;
// });
}
this.setState({
paused: false
});
this.events.onVideoPlay();
};
onRequestVideoMuteToggle = () => {
if (!this.player) return;
const newMuteValue = !this.player.localAudioMuted;
this.player.localAudioMuted = newMuteValue;
if (this.state.format === 'webrtc' && this.mediaStream) {
// const tracks = this.mediaStream.getTracks();
// tracks.forEach((track) => {
// if (track.kind === 'audio') {
// track.enabled = !newMuteValue;
// }
// });
}
this.setState({
muted: newMuteValue
});
this.events.onMute(newMuteValue);
};
onRequestDisposePlayer = () => {
if (!this.player) return;
this.player.dispose();
this.player = null;
this.mediaStream = null;
};
onRequestPreferredQualityChange = level => {
if (!this.player) return;
this.player.preferredLevel = level;
};
onRequestReloadPlayer = () => {
this.resetState(() => {
if (this.mediaStream) {
// this.mediaStream.getTracks().forEach((track) => {
// this.mediaStream?.removeTrack(track);
// });
}
this.player?.dispose();
this.player = null;
this.initManifestPlayer();
});
};
onRequestInitPlayer = () => {
if (this.player) return;
this.initManifestPlayer();
};
resetState = fn => {
this.setState({
format: undefined,
driver: null,
source: '',
availableQualities: []
}, fn);
};
render() {
if (this.props.children) {
return this.props.children({
player: this
});
} else {
return null;
}
}
}
exports.NativeFramePlayer = NativeFramePlayer;
//# sourceMappingURL=NativeFramePlayer.js.map