UNPKG

spectatr-player-sdk

Version:

A custom video player built with Stencil with Shaka Player integration

151 lines (150 loc) 6.12 kB
// @ts-ignore import shaka from "shaka-player"; import { fetchVideoSrc } from "../../services/videoService"; import { setUpPlayerEventListener } from "./event-handlers"; import { setupTracks } from "./tracker-util"; function handleLiveStream(component) { if (!component.player.isLive()) { console.warn('Source is not a n/ live stream!'); return; } component.isLive = true; const seekRange = component.player.seekRange(); if (seekRange.end !== Infinity) { component.videoElement.currentTime = seekRange.end; component.duration = seekRange.end; component.isDvrEnabled = true; } else { component.videoElement.currentTime = seekRange.end ?? 0; component.isDvrEnabled = false; console.warn('DVR not supported for this live stream.'); } component.progressUpdateInterval = setInterval(() => { const newSeekRange = component.player.seekRange(); if (newSeekRange.end !== Infinity && newSeekRange.end >= component.duration && component.isPlaying && !component.isLoading) { component.duration = newSeekRange.end; } }, 1000); component.livePollingInterval = setInterval(() => { if (!component.isLoading && component.isPlaying) fetchVideoSrc(component); }, 10000); //10 sec time polling } export async function setupVideo(component) { if (!component.clientId) return; if (!component.videoElement) return; try { component.isLoading = true; await fetchVideoSrc(component, true); if (!component.videoId) { component.setVideoId && component.setVideoId(component.tempVideoId); return; } if (!!component.scheduleTime && new Date(component.scheduleTime) > new Date()) { component.scheduleTimer = setInterval(async () => { if (new Date() >= new Date(component.scheduleTime)) { component.showStartStream = true; clearInterval(component.scheduleTimer); } }, 1000); } else { component.showStartStream = false; component.scheduleTime = null; } const support = await shaka.Player.probeSupport(); console.log('support.drm', support.drm); component.player.configure({ // Common configuration abr: { enabled: true }, streaming: { bufferingGoal: 60, // Larger buffer for live streams rebufferingGoal: 2, bufferBehind: 30, // Keep 30s of buffer behind the playhead ignoreTextStreamFailures: true, // Avoid failures if subtitles are missing preferNativeHls: true, // ← Replaces useNativeHlsOnSafari useNativeHlsForFairPlay: true, }, manifest: { hls: { defaultAudioCodec: 'mp4a.40.2', }, }, drm: !!component.token ? { servers: { 'com.widevine.alpha': 'https://drm-widevine-licensing.axprod.net/AcquireLicense', 'com.apple.fps.1_0': 'https://drm-fairplay-licensing.axprod.net/AcquireLicense', }, advanced: { 'com.apple.fps.1_0': { serverCertificateUri: 'https://vtb.axinom.com/FPScert/fairplay.cer', }, }, } : undefined, }); if (!!component.token) { component.player.getNetworkingEngine().registerRequestFilter((type, request) => { if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) { return; } // Axinom-specific headers request.headers['X-AxDRM-Message'] = component.token; request.headers['Content-Type'] = 'application/octet-stream'; // For FairPlay specifically if (request.uris[0].includes('fairplay')) { request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; } }); } if (!component.scheduleTime || new Date() >= new Date(component.scheduleTime)) await loadSrc(component); } catch (error) { component.isLoading = false; component.livePollingInterval = null; component.reactionPollingInterval = null; console.error('Error loading video:', error); component.videoError.emit('Error loading video'); await component.player.load(''); } } export async function loadSrc(component) { component.isLoading = true; await component.player.load(component.src.replace('https://stg-highlights-storage.s3.ap-south-1.amazonaws.com', 'https://d20mh0n8ctk3v.cloudfront.net')); component.isLoading = false; component.showStartStream = false; component.duration = component.videoElement.duration; setupTracks(component); if (component.videoElement.paused && (component.isPlaying || !!component.scheduleTime)) { component.scheduleTime = null; component.videoElement.play(); } if (component.livePollingInterval) { clearInterval(component.livePollingInterval); component.livePollingInterval = null; } if (component.progressUpdateInterval) { clearInterval(component.progressUpdateInterval); component.progressUpdateInterval = null; } if (component.reactionPollingInterval) { clearInterval(component.reactionPollingInterval); component.reactionPollingInterval = null; } // component.reactionPollingInterval = setInterval(() => { // pollVideoReactionCount(component); // }, 30000); if (component.player.isLive()) { handleLiveStream(component); } else { component.isDvrEnabled = true; } setUpPlayerEventListener(component); } //# sourceMappingURL=setup-utils.js.map