spectatr-player-sdk
Version:
A custom video player built with Stencil with Shaka Player integration
343 lines (339 loc) • 13.3 kB
JavaScript
import { j as addReaction } from './p-Bqc1mM21.js';
function setupTracks(component) {
const { player } = component;
if (!player)
return;
const audioTracks = player.getAudioTracks();
// Use a Map to store the first occurrence of each language
const uniqueLanguageTracks = new Map();
audioTracks.forEach(track => {
const language = track.language;
if (!uniqueLanguageTracks.has(language)) {
uniqueLanguageTracks.set(language, {
index: track.id,
language: language,
label: track.label || `Audio ${language}`,
enabled: track.active,
});
}
});
// Convert Map values back to an array
component.audioTracks = Array.from(uniqueLanguageTracks.values());
// Set the first track as active (or keep existing logic)
component.currentAudioTrack = 0;
setupQualityTrack(component);
}
function setupQualityTrack(component) {
const { player } = component;
if (!player)
return;
const tracks = player.getVariantTracks();
component.qualities = tracks
.filter(track => !track.label || track.label === component.audioTracks[component.currentAudioTrack]?.label)
.reduce((unique, track) => {
const qualityLabel = track.height ? `${track.height}p` : `${Math.floor(track.bandwidth / 1000)}kbps`;
unique.push({
index: track.id,
height: track.height,
bitrate: track.bandwidth,
name: qualityLabel,
});
return unique;
}, []);
component.currentQuality = -1;
}
function togglePlay(component) {
const video = component.videoElement;
if (video.paused) {
video.play();
component.playVideo.emit();
window.parent.postMessage({
type: 'ON_VIDEO_PLAY',
}, '*');
}
else {
video.pause();
component.pauseVideo.emit();
window.parent.postMessage({
type: 'ON_VIDEO_PAUSE',
}, '*');
}
}
function toggleMute(component) {
component.videoElement.muted = !component.videoElement.muted;
}
function setVolume(component, volume) {
if (volume !== 0 && component.videoElement.muted) {
component.videoElement.muted = false;
}
component.videoElement.volume = volume;
}
function seek(component, time) {
if (component.isLive) {
const dvrStartTime = component.player.seekRange().start;
component.videoElement.currentTime = Math.max(time, dvrStartTime);
component.currentTime = component.videoElement.currentTime;
}
else {
component.videoElement.currentTime = time;
component.currentTime = time;
}
}
function skipForward(component) {
component.videoElement.currentTime = Math.min(component.duration, component.videoElement.currentTime + 10);
}
function skipBackward(component) {
let seekToTime = component.videoElement.currentTime - 10;
if (component.isLive) {
const dvrStartTime = component.player.seekRange().start;
if (seekToTime < dvrStartTime) {
seekToTime = dvrStartTime;
}
}
component.videoElement.currentTime = seekToTime;
}
const toggleFullscreen = (component) => {
// Get the video container directly from the component reference
const videoContainer = component.videoContainer;
if (!videoContainer) {
console.error('Video container element not found');
component.videoError.emit('Video container element not found');
return;
}
if (!document.fullscreenElement) {
// Enter fullscreen
if (videoContainer.requestFullscreen) {
videoContainer
.requestFullscreen()
.then(() => {
component.isFullscreen = true;
})
.catch(err => {
console.error('Error attempting to enable fullscreen:', err);
component.videoError.emit('Error attempting to enable fullscreen');
});
}
}
else {
// Exit fullscreen
if (document.exitFullscreen) {
document
.exitFullscreen()
.then(() => {
component.isFullscreen = false;
})
.catch(err => {
console.error('Error attempting to exit fullscreen:', err);
component.videoError.emit('Error attempting to exit fullscreen');
});
}
}
};
function startProgressUpdate(component) {
component.progressUpdateInterval = setInterval(() => {
component.currentTime = component.videoElement.currentTime;
}, 100);
}
function stopProgressUpdate(component) {
if (component.progressUpdateInterval) {
clearInterval(component.progressUpdateInterval);
}
}
async function setQuality(component, qualityIndex) {
if (!component.player)
return;
if (qualityIndex === -1) {
// Auto quality
component.player.configure({ abr: { enabled: true } });
}
else {
// Specific quality
component.player.configure({ abr: { enabled: false } });
const tracks = component.player.getVariantTracks().filter(track => !track.label || track.label === component.audioTracks[component.currentAudioTrack]?.label);
component.player.selectVariantTrack(tracks[qualityIndex], true);
}
component.currentQuality = qualityIndex;
}
function setAudioTrack(component, trackIndex) {
if (!component.player)
return;
const audioTracks = component.player.getAudioTracks();
if (audioTracks[trackIndex]) {
component.player.selectAudioTrack(audioTracks[trackIndex]);
component.currentAudioTrack = trackIndex;
setupQualityTrack(component);
}
}
function toggleSettings(component, e) {
e.stopPropagation(); // Prevent component click from triggering the outside click handler
component.showSettings = !component.showSettings;
if (component.showSettings) {
component.showMainSettings = true;
component.showQualityOptions = false;
component.showAudioOptions = false;
}
}
function handleGoLive(component) {
component.duration = component.player.seekRange().end;
component.videoElement.currentTime = component.duration;
}
function handleClickOutsideSetting(component, event) {
if (!component.showSettings)
return;
const settingsMenu = component.hostElement.shadowRoot?.querySelector('.settings-menu');
const settingsButton = component.hostElement.shadowRoot?.querySelector('.control-btn');
// Check if click was outside both the menu and the settings button
const clickedInsideMenu = settingsMenu?.contains(event.target);
const clickedSettingsButton = settingsButton?.contains(event.target);
if (!clickedInsideMenu && !clickedSettingsButton) {
component.showSettings = false;
component.showQualityOptions = false;
component.showAudioOptions = false;
}
}
function shouldShowToggle(component) {
// Only show toggle if description is longer than 2 lines
return component.videoDescription.length > 200; // Adjust this threshold as needed
}
function toggleDescription(component) {
component.showFullDescription = !component.showFullDescription;
}
async function toggleLike(component) {
try {
component.isLiked = !component.isLiked;
component.isDisliked = false;
component.totalLikes = component.isLiked ? component.totalLikes + 1 : component.totalLikes - 1;
await addReaction(component, 'like');
}
catch (error) {
component.isLiked = !component.isLiked;
component.isDisliked = false;
component.totalLikes = component.isLiked ? component.totalLikes + 1 : component.totalLikes - 1;
console.error('like toggle failed:', error);
component.videoError.emit('React to video failed');
}
}
async function toggleDislike(component) {
const wasLiked = component.isLiked;
const wasDisliked = component.isDisliked;
const originalLikes = component.totalLikes;
try {
if (component.isLiked) {
component.isLiked = false;
component.totalLikes--;
}
component.isDisliked = !component.isDisliked;
await addReaction(component, 'dislike');
}
catch (error) {
component.isLiked = wasLiked;
component.isDisliked = wasDisliked;
component.totalLikes = originalLikes;
console.error('Dislike toggle failed:', error);
component.videoError.emit('React to video failed');
}
}
function formatTimeAgo(createdAt) {
const date = new Date(createdAt);
const now = new Date();
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
const intervals = {
year: 31536000,
month: 2592000,
week: 604800,
day: 86400,
hour: 3600,
minute: 60,
second: 1,
};
for (const [unit, secondsInUnit] of Object.entries(intervals)) {
const interval = Math.floor(seconds / secondsInUnit);
if (interval >= 1) {
return new Intl.RelativeTimeFormat('en', { numeric: 'auto' }).format(-interval, unit);
}
}
return 'just now';
}
function formatLikeCount(count) {
return Math.abs(count) >= 1e9
? (count / 1e9).toFixed(1).replace(/\.0$/, '') + 'B'
: Math.abs(count) >= 1e6
? (count / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'
: Math.abs(count) >= 1e3
? (count / 1e3).toFixed(1).replace(/\.0$/, '') + 'K'
: count.toString();
}
function getUserUUID(userId) {
if (userId)
return userId;
if (localStorage.getItem('spactatr_user_id')) {
return localStorage.getItem('spactatr_user_id');
}
else {
const id = crypto.randomUUID();
localStorage.setItem('spactatr_user_id', id);
return id;
}
}
function cleanupData(component) {
component.src = null;
component.token = null;
component.videoDescription = '';
component.videoTitle = '';
component.isLoading = true;
component.showPoll = false;
component.showQuiz = false;
component.pollAnswered = [];
component.quizAnswered = [];
component.quizzes = null;
component.timelineEvents = [];
component.isLive = false;
component.currentTime = 0;
component.duration = 0;
clearTimeout(component.controlsTimeout);
clearInterval(component.progressUpdateInterval);
clearInterval(component.livePollingInterval);
clearInterval(component.reactionPollingInterval);
}
function applyTheme(themeId, root) {
switch (themeId) {
case 'minimal-dark': //pass
root.style.setProperty('--vp-primary-bg', '#121212');
root.style.setProperty('--vp-controls-bg', 'rgba(0, 0, 0, 0.7)');
root.style.setProperty('--vp-accent', '#ff5555');
root.style.setProperty('--vp-video-text', '#ffffff');
root.style.setProperty('--vp-text', '#ffffff');
break;
case 'minimal-light': //pass
root.style.setProperty('--vp-primary-bg', '#f8f8f8');
root.style.setProperty('--vp-controls-bg', 'rgba(48, 48, 48, 0.7)');
root.style.setProperty('--vp-accent', '#e53e3e'); // Deep red for contrast
root.style.setProperty('--vp-video-text', '#ffffff');
root.style.setProperty('--vp-text', '#1a202c');
break;
case 'classic-youtube': //pass
root.style.setProperty('--vp-primary-bg', '#f9f9f9');
root.style.setProperty('--vp-controls-bg', 'rgba(0, 0, 0, 0.7)');
root.style.setProperty('--vp-accent', '#065fd4');
root.style.setProperty('--vp-video-text', '#ffffff');
root.style.setProperty('--vp-text', '#000');
break;
case 'cinema-mode': //pass
root.style.setProperty('--vp-primary-bg', '#f9f9f9');
root.style.setProperty('--vp-controls-bg', 'rgba(156, 3, 29, 0.45)');
root.style.setProperty('--vp-accent', '#cd2843ff');
root.style.setProperty('--vp-video-text', '#ffffff');
root.style.setProperty('--vp-text', '#000');
break;
case 'true-back': //pass
root.style.setProperty('--vp-primary-bg', '#000000');
root.style.setProperty('--vp-controls-bg', 'rgba(255, 255, 255, 0.3)');
root.style.setProperty('--vp-accent', '#000000');
root.style.setProperty('--vp-video-text', '#ffffff');
root.style.setProperty('--vp-text', '#aaaaaa');
break;
}
}
export { applyTheme as a, stopProgressUpdate as b, setupTracks as c, cleanupData as d, toggleDislike as e, formatLikeCount as f, getUserUUID as g, handleClickOutsideSetting as h, formatTimeAgo as i, shouldShowToggle as j, toggleDescription as k, skipBackward as l, togglePlay as m, skipForward as n, toggleMute as o, setVolume as p, toggleSettings as q, toggleFullscreen as r, startProgressUpdate as s, toggleLike as t, handleGoLive as u, seek as v, setQuality as w, setAudioTrack as x };
//# sourceMappingURL=p-CjB1Ea9v.js.map
//# sourceMappingURL=p-CjB1Ea9v.js.map