react-native-youtube-bridge
Version:
🎥 Easy-to-use YouTube player for React Native with cross-platform support
133 lines (131 loc) • 4.02 kB
JavaScript
;
class WebviewYoutubePlayerController {
commandId = 0;
pendingCommands = new Map();
constructor(webViewRef) {
this.webViewRef = webViewRef;
}
static createInstance(webViewRef) {
return new WebviewYoutubePlayerController(webViewRef);
}
getPendingCommands() {
return this.pendingCommands;
}
async play() {
await this.executeCommand('play');
}
async pause() {
await this.executeCommand('pause');
}
async stop() {
await this.executeCommand('stop');
}
async seekTo(seconds, allowSeekAhead = true) {
await this.executeCommand('seekTo', [seconds, allowSeekAhead]);
}
async setVolume(volume) {
await this.executeCommand('setVolume', [volume]);
}
async getVolume() {
return await this.executeCommand('getVolume', [], true);
}
async mute() {
await this.executeCommand('mute');
}
async unMute() {
await this.executeCommand('unMute');
}
async isMuted() {
return await this.executeCommand('isMuted', [], true);
}
async getCurrentTime() {
return await this.executeCommand('getCurrentTime', [], true);
}
async getDuration() {
return await this.executeCommand('getDuration', [], true);
}
async getVideoUrl() {
return await this.executeCommand('getVideoUrl', [], true);
}
async getVideoEmbedCode() {
return await this.executeCommand('getVideoEmbedCode', [], true);
}
async getPlaybackRate() {
return await this.executeCommand('getPlaybackRate', [], true);
}
async getAvailablePlaybackRates() {
return await this.executeCommand('getAvailablePlaybackRates', [], true);
}
async getPlayerState() {
return await this.executeCommand('getPlayerState', [], true);
}
async setPlaybackRate(suggestedRate) {
await this.executeCommand('setPlaybackRate', [suggestedRate]);
}
async getVideoLoadedFraction() {
return await this.executeCommand('getVideoLoadedFraction', [], true);
}
async loadVideoById(videoId, startSeconds, endSeconds) {
await this.executeCommand('loadVideoById', [videoId, startSeconds, endSeconds]);
}
async cueVideoById(videoId, startSeconds, endSeconds) {
await this.executeCommand('cueVideoById', [videoId, startSeconds, endSeconds]);
}
async setSize(width, height) {
await this.executeCommand('setSize', [width, height]);
}
async cleanup() {
await this.executeCommand('cleanup');
}
async updateProgressInterval(interval) {
await this.executeCommand('updateProgressInterval', [interval]);
}
executeCommand(command, args = [], needsResult = false) {
return new Promise(resolve => {
if (!this.webViewRef.current) {
resolve(null);
return;
}
const messageId = needsResult ? (++this.commandId).toString() : undefined;
if (needsResult && messageId) {
const timeout = setTimeout(() => {
this.pendingCommands.delete(messageId);
console.warn('Command timeout:', command, messageId);
resolve(null);
}, 5000);
this.pendingCommands.set(messageId, result => {
clearTimeout(timeout);
resolve(result);
});
}
const commandData = {
command,
args,
...(messageId && {
id: messageId
})
};
const injectScript = /* js */`
window.__execCommand && window.__execCommand(${JSON.stringify(commandData)}); true;
`;
this.webViewRef.current.injectJavaScript(injectScript);
if (!needsResult) {
resolve(null);
}
});
}
/**
* Updates player event callbacks. No-op in WebView implementation.
* This method exists for interface compatibility with web implementation.
* @param _newCallbacks - Event callbacks (ignored in WebView)
*/
updateCallbacks(_newCallbacks) {
// no-op only for web
}
async destroy() {
this.pendingCommands.clear();
await this.cleanup();
}
}
export default WebviewYoutubePlayerController;
//# sourceMappingURL=WebviewYoutubePlayerController.js.map