Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mirax-player

Package Overview
Dependencies
Maintainers
1
Versions
144
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mirax-player - npm Package Compare versions

Comparing version 6.2.0 to 6.3.0

src/angular/ExampleEmbed.md

843

dist/miraxEmbedder.js

@@ -1,408 +0,481 @@

/* # Mirax Player core license
const embedTwitter = (embedDiv) => {
function extractTwitterTweetId(url) {
const regex = /\/status\/(\d+)/;
const match = url.match(regex);
if (match && match[1]) {
return match[1];
} else {
return null; // No match found
}
}
Mirax Player is released under the MIT license:
const videoUrl = embedDiv.getAttribute("data-e-url");
const tweetId = extractTwitterTweetId(videoUrl);
const emWidth = embedDiv.getAttribute("data-e-width");
const emHeight = embedDiv.getAttribute("data-e-height");
const inputEmbedClip = document.createElement("style");
document.head.appendChild(inputEmbedClip);
const inputEmbedClipStyle = `
.mirax-embed {
position: relative;
width: 100%;
max-width: ${emWidth}px;
height: ${emHeight}px;
margin: 0 auto;
overflow: hidden;
}
.mirax-embed iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
inputEmbedClip.appendChild(document.createTextNode(inputEmbedClipStyle));
try {
// Create a div to hold the embedded tweet
const tweetContainer = document.createElement("div");
embedDiv.appendChild(tweetContainer);
// Set the ID for the tweet container
tweetContainer.id = `tweet-${tweetId}`;
// Add the Twitter widget script to the page and wait for it to load
const twitterWidgetScript = document.createElement("script");
twitterWidgetScript.src = "https://platform.twitter.com/widgets.js";
twitterWidgetScript.charset = "utf-8";
twitterWidgetScript.async = true;
// Attach a load event listener to the script
twitterWidgetScript.addEventListener("load", () => {
// The Twitter widget script has loaded, and the tweet is now embedded.
// You can perform any additional actions here if needed.
window.twttr.widgets.createTweet(tweetId, tweetContainer);
});
document.body.appendChild(twitterWidgetScript);
} catch (error) {
console.error("Error embedding Twitter content:", error);
}
};
// Function to embed a Dailymotion video using oEmbed
const embedDailymotion = (embedDiv) => {
MIT License
Copyright (c) [2023-present] [Demjhon Silver]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
const videoUrl = embedDiv.getAttribute("data-e-url");
const emWidth = embedDiv.getAttribute("data-e-width");
const emHeight = embedDiv.getAttribute("data-e-height");
import aziwork, { sunder } from 'aziwork';
const inputEmbedClip = document.createElement('style');
document.head.appendChild(inputEmbedClip);
const inputEmbedClipStyle = `
// Function to embed a Dailymotion video using oEmbed
const embedDailymotion = (video, container, videoClass) => {
const videoUrl = video.videoUrl;
// Define maxwidth and maxheight based on the video object's properties
const maxwidth = video.width || 640; // Default width if not provided
const maxheight = video.height || 360; // Default height if not provided
// Check if autoplay should be enabled (true by default)
const autoplayEnabled = video.autoplay !== undefined ? video.autoplay : true;
// Create a script element for the JSONP request
const script = document.createElement("script");
script.src = `https://www.dailymotion.com/services/oembed/?url=${encodeURIComponent(
videoUrl
)}&format=json&maxwidth=${maxwidth}&maxheight=${maxheight}&callback=handleDailymotionResponse`;
// Define a global callback function to handle the response
window.handleDailymotionResponse = (data) => {
if (data.html) {
// Create a div element to hold the Dailymotion video
const videoContainer = document.createElement("div");
// Apply the videoClass to the videoContainer
videoContainer.className = `video-${videoCount} ${videoClass} custom-dailymotion`; // Add custom-dailymotion class
// Set the HTML content of the videoContainer to the oEmbed HTML
videoContainer.innerHTML = data.html;
// Update the video's width to be responsive
const videoElement = videoContainer.querySelector('iframe');
if (videoElement) {
videoElement.style.width = '100%'; // Set width to 100% for responsiveness
// Conditionally add the 'autoplay' attribute
if (autoplayEnabled) {
videoElement.setAttribute('autoplay', 'autoplay');
}
// Update the 'allow' attribute to include 'fullscreen' and 'picture-in-picture'
videoElement.setAttribute('allow', 'autoplay; fullscreen; picture-in-picture; muted');
}
// Append the videoContainer to the provided container
container.appendChild(videoContainer);
// Clean up the script element and callback function
document.body.removeChild(script);
delete window.handleDailymotionResponse;
}
};
// Append the script element to the document to trigger the JSONP request
document.body.appendChild(script);
.mirax-embed {
position: relative;
width: 100%;
max-width: ${emWidth}px;
height:${emHeight}px;
margin: 0 auto;
overflow: hidden;
}
.mirax-embed iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
inputEmbedClip.appendChild(document.createTextNode(inputEmbedClipStyle));
// Create a script element for the JSONP request
const script = document.createElement("script");
script.src = `https://www.dailymotion.com/services/oembed/?url=${encodeURIComponent(
videoUrl
)}&format=json&callback=handleDailymotionResponse`;
// Define a global callback function to handle the response
window.handleDailymotionResponse = (data) => {
if (data.html) {
embedDiv.innerHTML = data.html;
}
// Clean up the script element and callback function
document.body.removeChild(script);
delete window.handleDailymotionResponse;
};
// Function to extract Vimeo video ID from a URL
const extractVimeoVideoId = (url) => {
const videoIdMatch = url.match(/\/(\d+)/);
if (videoIdMatch && videoIdMatch[1]) {
return videoIdMatch[1];
} else {
console.error("Invalid Vimeo video URL");
return "";
// Append the script element to the document to trigger the JSONP request
document.body.appendChild(script);
};
const embedTiktok = async (embedDiv) => {
try {
const videoUrl = embedDiv.getAttribute("data-e-url");
// Fetch oEmbed data from TikTok's API
const response = await fetch(`https://www.tiktok.com/oembed?url=${encodeURIComponent(videoUrl)}`);
if (!response.ok) {
throw new Error(`Failed to fetch TikTok oEmbed data: ${response.statusText}`);
}
};
const data = await response.json();
if (data.html) {
data.html = data.html.replace(/<script[^>]*>.*<\/script>/gi, "");
}
embedDiv.innerHTML = data.html;
const miraxBinderTikTok = document.createElement("script");
miraxBinderTikTok.src = "https://www.tiktok.com/embed.js";
document.body.appendChild(miraxBinderTikTok);
} catch (error) {
console.error(error);
}
};
// Function to extract YouTube video ID from a URL
const extractYouTubeVideoId = (url) => {
// Check if it's a YouTube Shorts URL
const shortsMatch = url.match(/(?:shorts\/|v=)([a-zA-Z0-9_-]{11})/);
if (shortsMatch && shortsMatch[1]) {
return shortsMatch[1];
}
// Check if it's a regular YouTube video URL
const videoIdMatch = url.match(/(\?v=|\/embed\/|\/watch\?v=|\/v\/|\/e\/|youtu.be\/)([^#&?]*).*/);
if (videoIdMatch && videoIdMatch[2].length === 11) {
return videoIdMatch[2];
}
throw new Error("Invalid YouTube video URL");
};
// Function to embed a YouTube video
const embedYouTube = (embedDiv) => {
const videoUrl = embedDiv.getAttribute("data-e-url");
const emWidth = embedDiv.getAttribute("data-e-width");
const emHeight = embedDiv.getAttribute("data-e-height");
const inputEmbedClip = document.createElement('style');
document.head.appendChild(inputEmbedClip);
const inputEmbedClipStyle = `
.mirax-embed {
display: flex;
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
position: relative;
width: 100%;
max-width: ${emWidth}px;
height: ${emHeight}px;
overflow: hidden;
text-align: center;
}
.mirax-embed iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
inputEmbedClip.appendChild(document.createTextNode(inputEmbedClipStyle));
const embedVimeo = (video, container, videoClass) => {
const emWidth = video.width || 640;
const emHeight = video.height || 360;
const controlsValue = video.controls;
const AutoplayValue = video.autoplay;
const LoopValue = video.loop;
const videoId = extractVimeoVideoId(video.videoUrl);
const playerDiv = document.createElement("div");
playerDiv.className = `video-${videoCount} ${videoClass}`;
playerDiv.dataset.eWidth = emWidth;
playerDiv.dataset.eHeight = emHeight;
playerDiv.dataset.efullscreen = video.fullscreen;
playerDiv.dataset.eVideoId = videoId;
container.appendChild(playerDiv);
const videoId = extractYouTubeVideoId(videoUrl);
// Check if the YouTube iframe API is already available
if (window.YT && window.YT.Player) {
initializeYouTubeAPI(embedDiv, videoId, {
width: emWidth, // Use the e-width attribute
height: emHeight, // Use the e-height attribute
});
} else {
// Define the callback function when the YouTube iframe API is ready
window.onYouTubeIframeAPIReady = () => {
initializeYouTubeAPI(embedDiv, videoId);
};
// Load the YouTube iframe API script
const script = document.createElement("script");
script.src = "https://player.vimeo.com/api/player.js";
script.src = "https://www.youtube.com/iframe_api";
script.async = true;
script.onload = () => {
const vimeoPlayer = new window.Vimeo.Player(playerDiv, {
id: videoId,
width: emWidth,
height: emHeight,
controls: controlsValue,
autoplay: AutoplayValue,
muted: true, // Set muted to true for autoplay
loop: LoopValue,
});
vimeoPlayer.ready().then(() => {
// You can use player methods here as needed
});
};
document.body.appendChild(script);
return () => {
if (playerDiv) {
playerDiv.innerHTML = "";
}
document.body.removeChild(script);
};
};
const embedTwitter = (video, container, videoClass) => {
const extractTwitterTweetId = (url) => {
const regex = /\/status\/(\d+)/;
const match = url.match(regex);
if (match && match[1]) {
return match[1];
} else {
return null; // No match found
}
};
try {
const videoUrl = video.videoUrl;
const tweetId = extractTwitterTweetId(videoUrl);
// Create a div to hold the embedded tweet
const tweetContainer = document.createElement("div");
// Apply the videoClass to the tweetContainer
tweetContainer.className = `video-${videoCount} ${videoClass}`;
// Set the ID for the tweet container
tweetContainer.id = `tweet-${tweetId}`;
// Add the Twitter widget script to the page and wait for it to load
const twitterWidgetScript = document.createElement("script");
twitterWidgetScript.src = "https://platform.twitter.com/widgets.js";
twitterWidgetScript.charset = "utf-8";
twitterWidgetScript.async = true;
// Attach a load event listener to the script
twitterWidgetScript.addEventListener("load", () => {
// The Twitter widget script has loaded, and the tweet is now embedded.
// You can perform any additional actions here if needed.
window.twttr.widgets.createTweet(tweetId, tweetContainer);
});
// Append the tweet container to the provided container
container.appendChild(tweetContainer);
container.appendChild(twitterWidgetScript);
} catch (error) {
console.error("Error embedding Twitter content:", error);
}
// Function to clean up the player
return () => {
if (embedDiv) {
embedDiv.innerHTML = ""; // Remove the YouTube player iframe
}
};
// Map to track embedded TikTok videos
const embeddedTikTokVideos = new Map();
const embedTiktok = (video, container, videoClass) => {
const videoUrl = video.videoUrl;
// Check if the TikTok video URL has already been embedded
if (embeddedTikTokVideos.has(videoUrl)) {
// Video has already been embedded, no need to embed it again
return;
};
// Function to initialize the YouTube API
const initializeYouTubeAPI = (embedDiv, videoId) => {
const emWidth = embedDiv.getAttribute("data-e-width");
const emHeight = embedDiv.getAttribute("data-e-height");
const emFS = embedDiv.getAttribute("data-e-fullscreen");
const emControls = embedDiv.getAttribute("data-e-controls");
const emAutoplay = embedDiv.getAttribute("data-e-autoplay");
const emLoop = embedDiv.getAttribute("data-e-loop");
const fullscreenValue = emFS === "false" ? 0 : 1;
const controlsValue = emControls === "false" ? 0 : 1;
const AutoplayValue = emAutoplay === "false" ? 0 : 1;
const AutomutedValue = emAutoplay === "false" ? 0 : 1;
const LoopValue = emLoop === "false" ? 0 : 1;
const inputEmbedClip = document.createElement('style');
document.head.appendChild(inputEmbedClip);
const inputEmbedClipStyle = `
.mirax-embed {
position: relative;
width: 100%;
max-width: ${emWidth}px;
height:${emHeight}px;
margin: 0 auto;
overflow: hidden;
}
// Mark the TikTok video URL as embedded
embeddedTikTokVideos.set(videoUrl, true);
const width = video.width || '100%'; // Default width if not provided
const height = video.height || '100%'; // Default height if not provided
aziwork.get(`https://www.tiktok.com/oembed?url=${encodeURIComponent(videoUrl)}`)
.then((response) => {
const data = sunder(response); // Parse JSON data using sunder
if (data.html) {
data.html = data.html.replace(/<script[^>]*>.*<\/script>/gi, '');
}
const videoContainer = document.createElement('div');
const videoCount = Date.now();
// Apply the videoClass to the videoContainer
videoContainer.className = `video-${videoCount} ${videoClass}`;
// Set the width and height of the videoContainer
videoContainer.style.width = width;
videoContainer.style.height = height;
videoContainer.innerHTML = data.html;
// Check if the TikTok embed script is already loaded
if (!document.querySelector('script[src="https://www.tiktok.com/embed.js"]')) {
// Dynamically load the TikTok embed script
const miraxBinderTikTok = document.createElement('script');
miraxBinderTikTok.src = 'https://www.tiktok.com/embed.js';
document.body.appendChild(miraxBinderTikTok);
}
if (container) {
// Append the videoContainer to the specified container (if provided)
container.appendChild(videoContainer);
} else if (document.body) {
// Append the videoContainer to the body if no container is specified
document.body.appendChild(videoContainer);
}
})
.catch((error) => {
console.error('An error occurred while embedding TikTok video:', error);
});
};
let videoCount = 1; // Initialize videoCount
const embedFacebook = (video, container, videoClass) => {
const videoUrl = video.videoUrl;
const autoplay = video.autoplay ? 'autoplay=true' : 'autoplay=false';
const muted = autoplay ? 'muted=true' : 'muted=false';
const emWidth = video.width || 640;
const emHeight = video.height || 360;
// Create an iframe element for the Facebook video
const iframe = document.createElement('iframe');
iframe.setAttribute('src', `https://www.facebook.com/plugins/video.php?href=${encodeURIComponent(videoUrl)}&width=${emWidth}&height=${emHeight}&show_text=false&${autoplay}&${muted}`);
iframe.setAttribute('width', emWidth);
iframe.setAttribute('height', emHeight);
iframe.setAttribute('frameborder', '0');
if (video.fullscreen) {
iframe.setAttribute('allowfullscreen', 'true');
.mirax-embed iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
iframe.className = `video-${videoCount} ${videoClass} custom-facebook`;
videoCount++;
container.appendChild(iframe);
};
// Function to extract YouTube video ID from a URL
const extractYouTubeVideoId = (url) => {
// Check if it's a YouTube Shorts URL
const shortsMatch = url.match(/(?:shorts\/|v=)([a-zA-Z0-9_-]{11})/);
if (shortsMatch && shortsMatch[1]) {
return shortsMatch[1];
`;
inputEmbedClip.appendChild(document.createTextNode(inputEmbedClipStyle));
if (embedDiv) {
new window.YT.Player(embedDiv, {
videoId: videoId,
width: emWidth, // Use the e-width attribute
height: emHeight, // Use the e-height attribute
playerVars: {
fs: fullscreenValue,
controls: controlsValue, // 0 or 1
cc_load_policy: 1,
autoplay: AutoplayValue,
mute: AutomutedValue,
loop: LoopValue
}
});
}
};
// Function to extract Vimeo video ID from a URL
const extractVimeoVideoId = (url) => {
const videoIdMatch = url.match(/\/(\d+)/);
if (videoIdMatch && videoIdMatch[1]) {
return videoIdMatch[1];
} else {
console.error("Invalid Vimeo video URL");
return "";
}
};
// Function to embed a Vimeo video
const embedVimeo = (embedDiv) => {
const videoUrl = embedDiv.getAttribute("data-e-url");
const emWidth = embedDiv.getAttribute("data-e-width");
const emHeight = embedDiv.getAttribute("data-e-height");
const emControls = embedDiv.getAttribute("data-e-controls");
const emAutoplay = embedDiv.getAttribute("data-e-autoplay");
const emLoop = embedDiv.getAttribute("data-e-loop");
const controlsValue = emControls === "false" ? 0 : 1;
const AutoplayValue = emAutoplay === "false" ? false : true;
const LoopValue = emLoop === "false" ? false : true;
const inputEmbedClip = document.createElement('style');
document.head.appendChild(inputEmbedClip);
const inputEmbedClipStyle = `
.mirax-embed {
position: relative;
width: 100%;
max-width: ${emWidth}px;
height:${emHeight}px;
margin: 0 auto;
overflow: hidden;
}
// Check if it's a regular YouTube video URL
const videoIdMatch = url.match(/(\?v=|\/embed\/|\/watch\?v=|\/v\/|\/e\/|youtu.be\/)([^#&?]*).*/);
if (videoIdMatch && videoIdMatch[2].length === 11) {
return videoIdMatch[2];
.mirax-embed iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
throw new Error("Invalid YouTube video URL");
`;
inputEmbedClip.appendChild(document.createTextNode(inputEmbedClipStyle));
const videoId = extractVimeoVideoId(videoUrl);
// Create a script element to load the Vimeo Player API
const script = document.createElement("script");
script.src = "https://player.vimeo.com/api/player.js";
script.async = true;
// Callback when the Vimeo Player API script is loaded
script.onload = () => {
const vimeoPlayer = new window.Vimeo.Player(embedDiv, {
id: videoId,
width: emWidth, // Use the e-width attribute
height: emHeight, // Use the e-height attribute
controls: controlsValue,
autolay: AutoplayValue,
muted: false,
loop: LoopValue,
responsive: true
});
vimeoPlayer.ready().then(() => {
// You can use player methods here as needed
});
};
const embedYouTube = (video, container, videoClass) => {
if (!container) {
console.error("Container element not found.");
return;
document.body.appendChild(script);
// Function to clean up the player
return () => {
if (embedDiv) {
embedDiv.innerHTML = ""; // Remove the Vimeo player iframe
}
const autoplayValue = video.autoplay ? 1 : 0;
const muteValue = video.autoplay ? 1 : video.muted ? 1 : 0;
const loopValue = video.autoplay ? 1 : video.loop ? 1 : 0;
const videoId = extractYouTubeVideoId(video.videoUrl);
// Create an iframe element for the YouTube player
const iframe = document.createElement("iframe");
iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=${autoplayValue}&mute=${muteValue}&loop=${loopValue ? 1 : 0}&controls=${video.controls ? 1 : 0}`;
iframe.width = video.width || 640;
iframe.height = video.height || 360;
iframe.frameborder = "0";
if (video.fullscreen) {
iframe.setAttribute("allow", "fullscreen");
}
// Apply the videoClass to the iframe element
iframe.className = videoClass;
// Append the iframe to the provided container
container.appendChild(iframe);
document.body.removeChild(script);
};
const embed = (videos) => {
videos.map((video) => {
const videoClass = video.videoClass || "";
const container = document.querySelector(`.${videoClass}`);
// Clear the container before embedding a new video
while (container.firstChild) {
container.removeChild(container.firstChild);
}
if (video.videoUrl.includes("youtube.com") || video.videoUrl.includes("youtu.be")) {
embedYouTube(video, container, videoClass);
}
else if (video.videoUrl.includes("facebook.com") || video.videoUrl.includes("fb.com")) {
embedFacebook(video, container, videoClass);
}
else if (video.videoUrl.includes("tiktok.com") || video.videoUrl.includes("tiktok")) {
embedTiktok(video, container, videoClass);
}
else if (video.videoUrl.includes("twitter.com")) {
embedTwitter(video, container, videoClass);
}
else if (video.videoUrl.includes("vimeo.com")) {
embedVimeo(video, container, videoClass);
}
else if (video.videoUrl.includes("dailymotion.com") || video.videoUrl.includes("dailymotion")) {
embedDailymotion(video, container, videoClass);
}
else {
throw new Error("Invalid video URL");
}
});
};
};
const embed = (selector) => {
const embedDiv = document.querySelector('.' + selector); // Prepend a dot symbol
const videoUrl = embedDiv.getAttribute("data-e-url");
if (videoUrl.includes("vimeo.com")) {
embedVimeo(embedDiv);
} else if (videoUrl.includes("youtube.com") || videoUrl.includes("youtu.be")) {
embedYouTube(embedDiv);
} else if (videoUrl.includes("tiktok.com") || videoUrl.includes("tiktok")) {
embedTiktok(embedDiv);
} else if (videoUrl.includes("dailymotion.com") || videoUrl.includes("dailymotion")) {
embedDailymotion(embedDiv);
} else if (videoUrl.includes("twitter.com")) {
embedTwitter(embedDiv);
} else {
throw new Error("Invalid video URL");
}
};
export default embed;

@@ -409,0 +482,0 @@

import './miraxplayerUI.js';
export function miraxPlayer(videoClip) {
function miraxPlayer(playerDiv) {
// Check if the control elements have already been created
const existingControls = videoClip.parentNode.querySelector('.mirax-theme');
const existingControls = playerDiv.parentNode.querySelector('.mirax-theme');
if (existingControls) {
return;
}
// Create control elements
const controlDiv = document.createElement("div");
// Append the control div to the videoClip element's parent node
videoClip.parentNode.appendChild(controlDiv);
// Append the control div to the playerDiv element's parent node
playerDiv.parentNode.appendChild(controlDiv);
// Error Handler if video file not exist or not found
videoClip.addEventListener("error", function () {
playerDiv.addEventListener("error", function () {
// Check the networkState
if (this.networkState > 2) {
// Create a text element
const videoText = document.createElement("p");
// Set the text content
videoText.textContent = "Video not found";
// Set the class name
videoText.className = "video-text";
// Append the text element to the video element's parent node
this.parentNode.appendChild(videoText);
}
});

@@ -86,50 +54,15 @@

//**********************************************//
//
// Player THEME
//
//*********************************************//
const playerTheme = videoClip.getAttribute("data-player-theme");
const playerTheme = playerDiv.getAttribute("data-player-theme");
controlDiv.className = "mirax-theme";
controlDiv.style.backgroundColor = playerTheme;

@@ -141,220 +74,108 @@

//**********************************************//
//
// PIP ( Picture in Picture )
//
//*********************************************//
const pipButton = document.createElement('mirax');
pipButton.className = 'pip-button';
controlDiv.appendChild(pipButton);
pipButton.addEventListener('click', () => {
if (document.pictureInPictureElement) {
// Exit PiP
document.exitPictureInPicture();
} else if (videoClip !== document.pictureInPictureElement) {
} else if (playerDiv !== document.pictureInPictureElement) {
// Request PiP
videoClip.requestPictureInPicture();
playerDiv.requestPictureInPicture();
}
});
videoClip.addEventListener('enterpictureinpicture', handleEnterPiP);
videoClip.addEventListener('leavepictureinpicture', handleLeavePiP);
playerDiv.addEventListener('enterpictureinpicture', handleEnterPiP);
playerDiv.addEventListener('leavepictureinpicture', handleLeavePiP);
function handleEnterPiP() {
// Update UI or perform actions when entering PiP
console.log('Enter PiP mode');
}
function handleLeavePiP() {
// Update UI or perform actions when leaving PiP
console.log('Exited PiP mode');
}
document.addEventListener('keydown', (event) => {
// Check if Alt+P is pressed
if (event.altKey && event.code === 'KeyP') {
// Toggle PiP mode
if (document.pictureInPictureElement) {
document.exitPictureInPicture();
} else {
videoClip.requestPictureInPicture();
playerDiv.requestPictureInPicture();
}
}
});
//______________________________________________________________________
//**********************************************//
//
// Play Button
//
//*********************************************//
// Define event listener and function for the play button
const playButton = document.createElement('mirax');
playButton.className = 'play-button';
playButton.addEventListener('click', playerButton);
controlDiv.appendChild(playButton);
function playerButton() {
if (videoClip.paused) {
videoClip.play();
if (playerDiv.paused) {
playerDiv.play();
playButton.classList.add("pause"); // Add the pause class name
} else {
videoClip.pause();
playerDiv.pause();
playButton.classList.remove("pause"); // Remove the pause class name
}
}
// Add event listener to the video element itself to toggle play state
videoClip.addEventListener('click', () => {
if (videoClip.paused) {
videoClip.play();
playerDiv.addEventListener('click', () => {
if (playerDiv.paused) {
playerDiv.play();
playButton.classList.add("pause");
} else {
videoClip.pause();
playerDiv.pause();
playButton.classList.remove("pause");
}
});
// Update the styles or UI of the play button based on video state
function updatePlayButton() {
if (videoClip.paused) {
if (playerDiv.paused) {
playButton.classList.remove("pause");
} else {
playButton.classList.add("pause");
}
}
// Listen to video play and pause events
videoClip.addEventListener('play', updatePlayButton);
videoClip.addEventListener('pause', updatePlayButton);
playerDiv.addEventListener('play', updatePlayButton);
playerDiv.addEventListener('pause', updatePlayButton);

@@ -364,42 +185,20 @@

//**********************************************//
//
// Backward Button >>
//
//*********************************************//
const backwardButton = document.createElement('mirax');
backwardButton.className = 'backward-button';
backwardButton.addEventListener('click', backwarderButton);
controlDiv.appendChild(backwardButton);
function backwarderButton() {
// Backward the video by 10 seconds
videoClip.currentTime = Math.max(videoClip.currentTime - 10, 0);
playerDiv.currentTime = Math.max(playerDiv.currentTime - 10, 0);
}

@@ -413,52 +212,23 @@

//**********************************************//
//
// Forward Button >>
//
//*********************************************//
const forwardButton = document.createElement('mirax');
forwardButton.className = 'forward-button';
forwardButton.addEventListener('click', forwarderButton);
controlDiv.appendChild(forwardButton);
function forwarderButton() {
// Forward the video by 10 seconds
videoClip.currentTime = Math.min(videoClip.currentTime + 10, videoClip.duration);
playerDiv.currentTime = Math.min(playerDiv.currentTime + 10, playerDiv.duration);
}

@@ -468,132 +238,70 @@

//______________________________________________________________________
//**********************************************//
//
// Play video - press space bar
//
//*********************************************//
// Add keydown event listener to the document
document.addEventListener('keydown', function(event) {
// Check if the pressed key is the space bar
// Check if the pressed key ctrl and space bar
if (event.code === 'Space') {
// Prevent the default action of scrolling
event.preventDefault();
// Call the same function that you use for the play button
playerButton();
if (event.ctrlKey) { // CTRL + SPACEBAR
// Call the same function that you use for the play button
playerButton();
}
}
});
//______________________________________________________________________
//**********************************************//
//
// Volume slider
//
//*********************************************//
let prevVolume = 1;
// Create the volume input element
const volumeInput = document.createElement('input');
volumeInput.type = 'range';
volumeInput.className = 'volume-slider';
volumeInput.min = '0';
volumeInput.max = '1';
volumeInput.step = '0.01';
volumeInput.defaultValue = '1';
// Add event listener to update volume
volumeInput.addEventListener('input', function() {
videoClip.volume = parseFloat(this.value);
playerDiv.volume = parseFloat(this.value);
});
controlDiv.appendChild(volumeInput);
//______________________________________________________________________
//**********************************************//
//
// Speed Options
//
//*********************************************//

@@ -603,275 +311,137 @@

//**********************************************//
//
// Speed Options
//
//*********************************************//
// Create a div element for the gear icon container
const gearIconContainer = document.createElement('div');
gearIconContainer.className = 'gear-icon';
gearIconContainer.style.width = '12px';
gearIconContainer.style.height = '12px';
gearIconContainer.style.position = 'absolute';
gearIconContainer.style.right = '29px';
gearIconContainer.style.right = '39px';
gearIconContainer.style.top = '9px';
gearIconContainer.style.cursor = 'pointer';
// Create a div element for the gear outer circle
const outerCircle = document.createElement('div');
outerCircle.className = 'outer-circle';
outerCircle.style.width = '12px';
outerCircle.style.height = '12px';
outerCircle.style.border = '1px solid white'; // Adjust border properties as needed
outerCircle.style.borderRadius = '50%';
outerCircle.style.position = 'absolute';
outerCircle.style.boxSizing = 'border-box';
const horizontalLine = document.createElement('div');
horizontalLine.className = 'horizontal-line';
horizontalLine.style.width = '6px'; // Adjust the width as needed
horizontalLine.style.height = '2px';
horizontalLine.style.backgroundColor = 'white'; // Change color as needed
horizontalLine.style.position = 'absolute';
horizontalLine.style.top = '55%';
horizontalLine.style.left = '35%';
horizontalLine.style.transform = 'translate(-50%, -50%)';
// Create a div element for the vertical line of the "L" flip shape
const verticalLine = document.createElement('div');
verticalLine.className = 'vertical-line';
verticalLine.style.width = '2px';
verticalLine.style.height = '6px'; // Adjust the height as needed
verticalLine.style.backgroundColor = 'white'; // Change color as needed
verticalLine.style.position = 'absolute';
verticalLine.style.top = '30%';
verticalLine.style.left = '50%';
verticalLine.style.transform = 'translate(-50%, -50%)';
// Append the horizontal and vertical lines to the gear icon container
gearIconContainer.appendChild(horizontalLine);
gearIconContainer.appendChild(verticalLine);
// Append the outer circle to the gear icon container
gearIconContainer.appendChild(outerCircle);
// Add the gear icon container to your player's UI
controlDiv.appendChild(gearIconContainer);
// Create a div element for the tooltip
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.style.width = '80px';
tooltip.style.height = '150px';
tooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
tooltip.style.color = 'white';
tooltip.style.position = 'absolute';
tooltip.style.display = 'none';
tooltip.style.zIndex = '100';
tooltip.style.fontFamily = 'Arial, Corbel';
tooltip.style.fontWeight = 'normal';
tooltip.style.fontSize = '11px';
tooltip.style.lineHeight = '19px';
// Adjust the top property to make the tooltip appear above the gear icon
tooltip.style.right = '40px';
tooltip.style.bottom = '30px'; // Change this value to position the tooltip above the gear icon
tooltip.style.padding = '5px';
// Create a div element for the tooltipzz
// Add speed options to the tooltip
const tooltipzz = document.createElement('div');
tooltipzz.className = 'tooltipzz';
tooltipzz.style.width = '80px';
tooltipzz.style.height = '160px';
tooltipzz.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
tooltipzz.style.color = 'white';
tooltipzz.style.position = 'absolute';
tooltipzz.style.display = 'none';
tooltipzz.style.zIndex = '100';
tooltipzz.style.fontFamily = 'Arial, Corbel';
tooltipzz.style.fontWeight = 'normal';
tooltipzz.style.fontSize = '11px';
tooltipzz.style.lineHeight = '19px';
// Adjust the top property to make the tooltipzz appear above the gear icon
tooltipzz.style.right = '40px';
tooltipzz.style.bottom = '-5px'; // Change this value to position the tooltipzz above the gear icon
tooltipzz.style.padding = '5px';
// Add speed options to the tooltipzz
// Add speed options to the tooltip
const speedOptions = [
{ value: 0.25, label: '0.25x' },
{ value: 0.5, label: '0.5x' },
{ value: 0.75, label: '0.75x' },
{ value: 1, label: 'Normal' },
{ value: 1.25, label: '1.25x' },
{ value: 1.5, label: '1.5x' },
{ value: 1.75, label: '1.75x' },
{ value: 2, label: '2x' }
];
let selectedOption = null; // Track the selected option
speedOptions.forEach((option) => {
const optionElement = document.createElement('div');
optionElement.className = 'speed-option'; // Add this class for event handling
optionElement.textContent = option.label;
optionElement.style.cursor = 'pointer';
tooltip.appendChild(optionElement);
tooltipzz.appendChild(optionElement);
optionElement.addEventListener('click', () => {
// Extract the numeric value from the label
const speedValue = parseFloat(option.value);
changePlaybackSpeed(speedValue);
// Update the selected option and indicator
selectedOption = optionElement;
updateSelectedIndicator();
});
// Add mouseover and mouseout event listeners to change background color
optionElement.addEventListener('mouseover', () => {
optionElement.style.backgroundColor = 'rgba(45, 85, 255, 0.8)'; // Blue background on hover
});
optionElement.addEventListener('mouseout', () => {
// Remove background color on mouseout, but skip the selected option
if (optionElement !== selectedOption) {
optionElement.style.backgroundColor = '';
}
});
});
// Function to update the visual indicator for the selected option
function updateSelectedIndicator() {
speedOptionElements.forEach((optionElement) => {
if (optionElement === selectedOption) {
optionElement.style.backgroundColor = 'rgba(45, 85, 255, 1)'; // Set the selected option's background color
optionElement.style.color = 'white'; // Set text color for better visibility
optionElement.style.borderRadius = '2px';
} else {
optionElement.style.backgroundColor = ''; // Remove background color from other options
optionElement.style.color = ''; // Remove text color from other options
}
});
}

@@ -884,77 +454,36 @@

// Add the tooltip to the player's UI
controlDiv.appendChild(tooltip);
// Remove the initial 'display: none' style from the tooltip
tooltip.style.display = 'none';
// Add the tooltipzz to the player's UI
controlDiv.appendChild(tooltipzz);
// Remove the initial 'display: none' style from the tooltipzz
tooltipzz.style.display = 'none';
// Add event listeners for mouseover and mouseout to show/hide the tooltipzz
// Add event listeners for mouseover and mouseout to show/hide the tooltip
gearIconContainer.addEventListener('mouseover', () => showTooltip());
tooltip.addEventListener('mouseover', () => showTooltip());
tooltip.addEventListener('mouseout', () => hideTooltip());
tooltipzz.addEventListener('mouseover', () => showTooltip());
tooltipzz.addEventListener('mouseout', () => hideTooltip());
// Function to show the tooltipzz
// Function to show the tooltip
function showTooltip() {
tooltipzz.style.display = 'block';
tooltip.style.display = 'block';
}
// Function to hide the tooltipzz
// Function to hide the tooltip
function hideTooltip() {
tooltipzz.style.display = 'none';
tooltip.style.display = 'none';
}
// Add event listeners to the speed options in the tooltipzz
const speedOptionElements = tooltipzz.querySelectorAll('.speed-option');
// Add event listeners to the speed options in the tooltip
const speedOptionElements = tooltip.querySelectorAll('.speed-option');
speedOptionElements.forEach((optionElement) => {
optionElement.addEventListener('click', () => {
const speedValue = parseFloat(optionElement.textContent);
changePlaybackSpeed(speedValue);
});
});
// Function to change the playback speed of the video
function changePlaybackSpeed(speed) {
videoClip.playbackRate = speed;
playerDiv.playbackRate = speed;
hideTooltip();
}

@@ -970,68 +499,30 @@

//**********************************************//
//
// Speaker UI icon
//
//*********************************************//
let xSymbolInterval;
// Function to toggle the visibility of the xSymbol
function toggleXSymbol() {
xSymbol.style.visibility = xSymbol.style.visibility === 'visible' ? 'hidden' : 'visible';
}
// Add event listener to update xSymbol visibility when video play/pause
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1042,47 +533,22 @@

// Create a div element for the speaker icon container
const speakerIconContainer = document.createElement('div');
speakerIconContainer.className = 'speaker-icon';
speakerIconContainer.style.width = '20px';
speakerIconContainer.style.height = '50px';
speakerIconContainer.style.position = 'absolute';
speakerIconContainer.style.marginRight = '87px';
speakerIconContainer.style.right = '0'; // Set the right property to auto
speakerIconContainer.style.cursor = 'pointer';
// Get the volume slider element
const volumeSlider = document.querySelector('.volume-slider');
volumeSlider.style.opacity = '0'; // Initially hide the volume slider
// Add a mouseenter event listener to show the volume slider when hovering over the speaker icon
speakerIconContainer.addEventListener('mouseenter', () => {
volumeSlider.style.opacity = '1';
});
// Gear Icon pure javascript:

@@ -1096,86 +562,40 @@

// Add a wheel event listener to the volume slider
volumeSlider.addEventListener('wheel', function (event) {
// Prevent the default scrolling behavior
event.preventDefault();
// Calculate the new volume value based on the mouse wheel delta
const delta = event.deltaY > 0 ? -0.1 : 0.1; // Adjust the step as needed
let newVolume = parseFloat(this.value) + delta;
// Ensure the volume stays within the range [0, 1]
newVolume = Math.max(0, Math.min(1, newVolume));
// Update the volume slider value and video volume
this.value = newVolume;
playerDiv.volume = newVolume;
videoClip.volume = newVolume;
// Update the x symbol based on the volume value
if (newVolume === 0) {
xSymbol.textContent = 'x';
volumeInput.style.backgroundColor = '#FF004F';
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
speakerBox.style.backgroundColor = '#FF004F';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1186,55 +606,26 @@

}
else if (newVolume <= 0.5 ) {
xSymbol.textContent = '|';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
volumeInput.style.backgroundColor = 'orange';
xSymbol.style.color = 'orange';
speakerBox.style.backgroundColor = 'orange';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'orange';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'orange';
});

@@ -1248,64 +639,29 @@

}
else {
xSymbol.textContent = ')';
volumeInput.style.backgroundColor = 'white';
speakerBox.style.backgroundColor = 'white';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});
}
});

@@ -1323,20 +679,5 @@

// Add a mouseleave event listener to hide the volume slider when not hovering over the speaker icon
speakerIconContainer.addEventListener('mouseleave', () => {
volumeSlider.style.opacity = '0';
});

@@ -1347,81 +688,39 @@

// Add a wheel event listener to the speaker icon container
speakerIconContainer.addEventListener('wheel', function (event) {
// Prevent the default scrolling behavior
event.preventDefault();
// Calculate the new volume value based on the mouse wheel delta
const delta = event.deltaY > 0 ? -0.1 : 0.1; // Adjust the step as needed
let newVolume = parseFloat(volumeSlider.value) + delta;
// Ensure the volume stays within the range [0, 1]
newVolume = Math.max(0, Math.min(1, newVolume));
// Update the volume slider value and video volume
volumeSlider.value = newVolume;
playerDiv.volume = newVolume;
videoClip.volume = newVolume;
// Update the x symbol based on the volume value
if (newVolume === 0) {
volumeInput.style.backgroundColor = '#FF004F';
xSymbol.textContent = 'x';
xSymbol.style.fontSize= '11px';
xSymbol.style.top = '16px';
xSymbol.style.top = '18px';
xSymbol.style.color = 'white';
speakerBox.style.backgroundColor = '#FF004F';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1431,50 +730,24 @@

}
else if (newVolume <= 0.5 ) {
xSymbol.textContent = '|';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
volumeInput.style.backgroundColor = 'orange';
speakerBox.style.backgroundColor = 'orange';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'orange';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'orange';
});

@@ -1484,62 +757,30 @@

}
else {
xSymbol.textContent = ')';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
volumeInput.style.backgroundColor = 'white';
speakerBox.style.backgroundColor = 'white';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});
}
});

@@ -1550,25 +791,11 @@

// Add a mouseenter event listener to show the volume slider when hovering over the volume slider
volumeSlider.addEventListener('mouseenter', () => {
volumeSlider.style.opacity = '1';
});
// Add a mouseleave event listener to hide the volume slider when not hovering over the volume slider
volumeSlider.addEventListener('mouseleave', () => {
volumeSlider.style.opacity = '0';
});

@@ -1579,43 +806,36 @@

// Create a div element for the speaker box
const speakerBox = document.createElement('div');
speakerBox.className = 'box';
speakerBox.style.width = '6px';
speakerBox.style.height = '6px';
speakerBox.style.backgroundColor = 'white';
speakerBox.style.position = 'absolute';
speakerBox.style.left = '3px';
speakerBox.style.top = '22px';
const speakerTrapezoid = document.createElement('div');
speakerTrapezoid.className = 'speakerTrapezoid';
speakerTrapezoid.style.borderBottom = '6px solid white';
speakerTrapezoid.style.borderLeft = '3px solid transparent';
speakerTrapezoid.style.borderRight = '3px solid transparent';
speakerTrapezoid.style.height = '10';
speakerTrapezoid.style.width = '6px';
speakerTrapezoid.style.transform = 'rotate(-90deg)';
speakerTrapezoid.style.marginLeft ='2px';
speakerTrapezoid.style.marginTop ='22px';
document.body.appendChild(speakerTrapezoid);
// Append the speaker box and cone to the speaker icon container
speakerIconContainer.appendChild(speakerBox);
speakerIconContainer.appendChild(speakerTrapezoid);
// Append the speaker icon container to the controlDiv
controlDiv.appendChild(speakerIconContainer);

@@ -1625,92 +845,45 @@

//______________________________________________________________________
// Create a span element for the ")" symbol
const xSymbol = document.createElement('span');
xSymbol.className = 'x-symbol';
xSymbol.textContent = ')';
xSymbol.style.fontSize = '8px';
xSymbol.style.color = 'white'; // Set the color to white once
xSymbol.style.position = 'absolute';
xSymbol.style.left = '15px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
xSymbol.style.fontFamily = 'Arial, Corbel';
// Append the ")" symbol to the speaker icon container
speakerIconContainer.appendChild(xSymbol);
// Add event listener to update volume and x symbol
volumeInput.addEventListener('input', function () {
// Use the video element directly
playerDiv.volume = parseFloat(this.value);
videoClip.volume = parseFloat(this.value);
// Update the x symbol based on the volume value
if (videoClip.volume === 0) {
if (playerDiv.volume === 0) {
xSymbol.textContent = 'x';
xSymbol.style.fontSize = '11px';
xSymbol.style.top = '16px';
xSymbol.style.top = '18px';
// Change the background color of the volume slider to #FF004F
volumeInput.style.backgroundColor = '#FF004F';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1721,53 +894,25 @@

}
else if (videoClip.volume <= 0.5 ) {
else if (playerDiv.volume <= 0.5 ) {
xSymbol.textContent = '|';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
volumeInput.style.backgroundColor = 'orange';
speakerBox.style.backgroundColor = 'orange';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'orange';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'orange';
});

@@ -1779,54 +924,25 @@

}
else {
xSymbol.textContent = ')';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
volumeInput.style.backgroundColor = 'white';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1836,8 +952,3 @@

}
});

@@ -1849,78 +960,37 @@

// Add event listener to the speaker icon container
speakerIconContainer.addEventListener("click", function() {
// Toggle the mute state of the video element
videoClip.muted = !videoClip.muted;
playerDiv.muted = !playerDiv.muted;
// Change the color of the speaker icon based on the mute state
if (videoClip.muted) {
if (playerDiv.muted) {
// Set the color to gray
speakerBox.style.backgroundColor = "#FF004F";
// Change the background color of the volume slider to #FF004F
xSymbol.textContent = 'x';
xSymbol.style.fontSize = '11px';
xSymbol.style.top = '16px';
xSymbol.style.top = '18px';
volumeInput.style.backgroundColor = '#FF004F';
prevVolume = volumeInput.value;
volumeInput.value = '0';
videoClip.volume = 0;
playerDiv.volume = 0;
speakerBox.style.backgroundColor = '#FF004F';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});

@@ -1930,92 +1000,45 @@

} else {
// Set the color to white
speakerBox.style.backgroundColor = "white";
volumeInput.style.backgroundColor = 'white';
xSymbol.textContent = ')';
xSymbol.style.fontSize = '8px';
xSymbol.style.top = '19px';
xSymbol.style.top = '20px';
// Restore the previous volume value after unmuting
volumeInput.value = prevVolume;
videoClip.volume = parseFloat(prevVolume);
playerDiv.volume = parseFloat(prevVolume);
speakerBox.style.backgroundColor = 'white';
videoClip.addEventListener('play', () => {
playerDiv.addEventListener('play', () => {
// Start toggling the symbol every 500 milliseconds (adjust timing as needed)
xSymbolInterval = setInterval(toggleXSymbol, 700);
xSymbol.style.color = 'white';
});
videoClip.addEventListener('pause', () => {
playerDiv.addEventListener('pause', () => {
// Stop toggling and make the symbol visible
clearInterval(xSymbolInterval);
xSymbol.style.visibility = 'visible';
xSymbol.style.color = 'white';
});
}
});
//**********************************************//
//
// Progress bar slider with scroll bar, mouse wheel, and keyboard shortcuts
//
//*********************************************//
const progressBar = document.createElement('progress');
progressBar.className = 'progress-bar';
progressBar.min = '0';
progressBar.max = '100';
progressBar.value = '0';
controlDiv.appendChild(progressBar);

@@ -2025,124 +1048,61 @@

videoClip.addEventListener('timeupdate', function() {
const percentPlayed = (videoClip.currentTime / videoClip.duration) * 100;
playerDiv.addEventListener('timeupdate', function() {
const percentPlayed = (playerDiv.currentTime / playerDiv.duration) * 100;
progressBar.value = percentPlayed;
});
progressBar.addEventListener('mousedown', function(e) {
handleProgressBarClick(e);
});
// Function to handle mouse wheel events
progressBar.addEventListener('wheel', function(e) {
e.preventDefault(); // Prevent the default scroll behavior
const delta = e.deltaY; // Get the scrolling direction (positive or negative)
// Adjust the video's current time based on the scrolling direction
const step = 1; // You can adjust the step size as needed
const currentTime = playerDiv.currentTime + (delta > 0 ? step : -step);
const currentTime = videoClip.currentTime + (delta > 0 ? step : -step);
// Ensure the currentTime stays within the video's duration limits
playerDiv.currentTime = Math.min(Math.max(currentTime, 0), playerDiv.duration);
videoClip.currentTime = Math.min(Math.max(currentTime, 0), videoClip.duration);
// Update the progress bar value
progressBar.value = (videoClip.currentTime / videoClip.duration) * 100;
progressBar.value = (playerDiv.currentTime / playerDiv.duration) * 100;
});
function handleProgressBarClick(e) {
const rect = progressBar.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
const newProgress = (offsetX / rect.width) * 100;
playerDiv.currentTime = (newProgress / 100) * playerDiv.duration;
videoClip.currentTime = (newProgress / 100) * videoClip.duration;
const onMouseMove = function(e) {
const offsetX = e.clientX - rect.left;
const newProgress = (offsetX / rect.width) * 100;
videoClip.currentTime = (newProgress / 100) * videoClip.duration;
playerDiv.currentTime = (newProgress / 100) * playerDiv.duration;
};
const onMouseUp = function() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
// Function to handle keyboard shortcuts
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowLeft') {
// Rewind the video by 10 seconds
videoClip.currentTime = Math.max(videoClip.currentTime - 10, 0);
playerDiv.currentTime = Math.max(playerDiv.currentTime - 10, 0);
e.preventDefault(); // Prevent the default behavior of scrolling the page
} else if (e.key === 'ArrowRight') {
// Forward the video by 10 seconds
videoClip.currentTime = Math.min(videoClip.currentTime + 10, videoClip.duration);
playerDiv.currentTime = Math.min(playerDiv.currentTime + 10, playerDiv.duration);
e.preventDefault(); // Prevent the default behavior of scrolling the page
}
});

@@ -2153,15 +1113,6 @@

//**********************************************//
//
// Dynamic Player Width
//
//*********************************************//

@@ -2174,2 +1125,4 @@

const dynamicWidth = playerDiv.getAttribute("data-player-width");
const dynamicFloat = playerDiv.getAttribute("data-player-float");

@@ -2182,56 +1135,20 @@

const dynamicWidth = videoClip.getAttribute("data-player-width");
const dynamicFloat = videoClip.getAttribute("data-player-float");
const inputPlayerClip = document.createElement('style');
document.head.appendChild(inputPlayerClip);
const inputPlayerClipStyle = `
.mirax-player {
min-width:300px;
min-width:350px;
max-width: ${dynamicWidth + 400}px;
width: 100%; /* This ensures the video fills its container while respecting max-width */
height: auto; /* This maintains the video's aspect ratio */
min-height:100px;
max-height:450px;
background-color: #000000;
margin: 0 auto;
}
:root {
--progress-width: 100%;
}

@@ -2241,58 +1158,45 @@

/* Hide the control div by default */
.mirax-theme {
display: none;
transition: transform 0.3s;
}
/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
display: block;
margin: 0 auto;
position: relative;
width: 100%;
height: 20px;
min-width:350px;
max-width: 95%;
min-width: 300px;
height: 30px;
background-color: rgba(0, 0, 0, 0.5);
margin-top:-44px;
bottom: 0;
left: 10;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
padding-top:5px;
padding-bottom:5px;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
}
.progress-bar {
display: block;
margin: 0 auto;
position: relative;
margin-top:-49px;
margin-top:-36px;
width: 100%;
width: var(--progress-width);
max-width: var(--progress-max-width);
height: 14px;
background-color: rgba(0, 0, 0, 0.1);
height: 6px;
background-color: rgba(255, 255, 255, 0.1);
border-style: none;
}

@@ -2302,21 +1206,11 @@

.player-selector {
margin: 0 auto;
width: 100%;
max-width: ${dynamicWidth}px;
position: relative;
float: ${dynamicFloat};
text-align: center;
}
`;
inputPlayerClip.appendChild(document.createTextNode(inputPlayerClipStyle));

@@ -2333,129 +1227,60 @@

//**********************************************//
//
// Timestamp Math System
//
//*********************************************//
// After creating the currentTimeDiv
const currentTimeDiv = document.createElement('div');
currentTimeDiv.className = 'current-time';
controlDiv.appendChild(currentTimeDiv);
// After creating the timeDurationDiv
const timeDurationDiv = document.createElement('div');
timeDurationDiv.className = 'time-duration';
controlDiv.appendChild(timeDurationDiv);
// Set the initial margin-left to 40px for timeDurationDiv
timeDurationDiv.style.marginLeft = '40px';
currentTimeDiv.style.marginLeft = '10px';
currentTimeDiv.style.textAlign = 'right';
// Listen to the timeupdate event to update the current time and adjust margin
playerDiv.addEventListener('timeupdate', updateCurrentTime);
videoClip.addEventListener('timeupdate', updateCurrentTime);
// Function to update the current time in the currentTimeDiv
function updateCurrentTime() {
const currentTime = videoClip.currentTime;
const currentTime = playerDiv.currentTime;
const formattedTime = formatTime(currentTime);
currentTimeDiv.textContent = formattedTime;
timeDurationDiv.style.opacity = '1';
// Check if the current time is greater than or equal to 1 minute (01:00)
if (currentTime >= 60) {
// #FF004Fuce marginLeft by 40px
timeDurationDiv.style.marginLeft = '40px';
}
// Check if the current time is greater than or equal to 10 minutes (10:00)
if (currentTime >= 600) {
// #FF004Fuce marginLeft by 45px
timeDurationDiv.style.marginLeft = '45px';
}
// Check if the current time is greater than or equal to 1 hour (01:00:00)
if (currentTime >= 3600) {
// #FF004Fuce marginLeft by 63px
timeDurationDiv.style.marginLeft = '63px';
}
// Check if the current time is greater than or equal to 10 hour (10:00:00)
if (currentTime >= 36000) {
// #FF004Fuce marginLeft by 69px
timeDurationDiv.style.marginLeft = '69px';
}
}

@@ -2465,132 +1290,70 @@

// Function to update time duration
function updateDuration(videoClip, timeDurationDiv) {
if (!isNaN(videoClip.duration)) {
const formattedDuration = formatTime(videoClip.duration);
function updateDuration(playerDiv, timeDurationDiv) {
if (!isNaN(playerDiv.duration)) {
const formattedDuration = formatTime(playerDiv.duration);
timeDurationDiv.textContent = formattedDuration;
}
}
// Function to format time in HH:MM:SS with conditional zero-padding
function formatTime(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);
let formattedTime = '';
if (hours >= 1) {
formattedTime += `${hours.toString()}:`;
}
formattedTime += `${minutes.toString().padStart(1, '0')}:${secs.toString().padStart(2, '0')}`;
return formattedTime;
}
// Set initial content of currentTimeDiv
currentTimeDiv.textContent = formatTime(0);
// Listen to the timeupdate event to update the current time and adjust margin
playerDiv.addEventListener('timeupdate', updateCurrentTime);
videoClip.addEventListener('timeupdate', updateCurrentTime);
// Listen to the loadedmetadata event to update time duration and adjust margin
playerDiv.addEventListener('loadedmetadata', () => updateDuration(playerDiv, timeDurationDiv));
videoClip.addEventListener('loadedmetadata', () => updateDuration(videoClip, timeDurationDiv));
//**********************************************//
//
// Progress bar value color
//
//*********************************************//
const playerBar = videoClip.getAttribute("data-player-bar");
const playerBar = playerDiv.getAttribute("data-player-bar");
var color_progress_bar = playerBar;
const inputProgressBar = document.createElement('style');
document.head.appendChild(inputProgressBar);
const inputProgressBarStyle = `
progress::-webkit-progress-bar {
background-color: rgba(255, 255, 255, 0.1);
position:relative;
}
progress::-webkit-progress-value {
background-color: ${color_progress_bar};
position:relative;
}
progress[value]::-moz-progress-bar {
background-color: ${color_progress_bar};
position:relative;
}
progress::-ms-fill {
background-color: ${color_progress_bar};
position:relative;

@@ -2600,13 +1363,71 @@

}
progress::-ms-fill {
progress::-webkit-slider-thumb {
width: 11px;
height: 11px;
margin-top:-1px;
border-radius: 100%;
background-color: red;
border-style: none;
cursor: pointer;
-webkit-appearance: none; /* Remove default appearance for Chrome, Safari and Opera */
-moz-appearance: none; /* Remove default appearance for Firefox */
appearance: none; /* Remove default appearance for Edge */
}
progress::-moz-range-thumb {
width: 11px;
height: 11px;
margin-top:-1px;
border-radius: 100%;
background-color: red;
border-style: none;
cursor: pointer;
-webkit-appearance: none; /* Remove default appearance for Chrome, Safari and Opera */
-moz-appearance: none; /* Remove default appearance for Firefox */
appearance: none; /* Remove default appearance for Edge */
}
background-color: ${color_progress_bar};
position:relative;
}
`;
inputProgressBar.appendChild(document.createTextNode(inputProgressBarStyle));
//**********************************************//
//
// Double Click Fullscreen
//
//*********************************************//
playerDiv.addEventListener('dblclick', toggleFullscreen);
//______________________________________________________________________
//**********************************************//
//
// Fullscreen Button
//
//*********************************************//
// Existing code for the fullscreen button
const fullscreenButton = document.createElement('mirax');
fullscreenButton.className = 'fullscreen';
controlDiv.appendChild(fullscreenButton);
fullscreenButton.addEventListener('click', toggleFullscreen);

@@ -2617,57 +1438,113 @@

progress::-webkit-slider-thumb {
function toggleFullscreen() {
const video = document.querySelector('.mirax-player');
if (document.documentElement.requestFullscreen) {
if (!document.fullscreenElement) {
// Store the original video dimensions
video.dataset.originalWidth = video.style.width;
video.dataset.originalHeight = video.style.height;
width: 11px;
// Calculate video's aspect ratio
const videoAspectRatio = video.videoWidth / video.videoHeight;
height: 11px;
if (videoAspectRatio > 1) {
// Video is landscape (16:9 or wider)
video.style.width = '100%';
video.style.height = '100%';
} else {
// Video is portrait (9:16 or taller)
// Calculate the height to maintain 9:16 aspect ratio with increased height
const screenHeight = window.innerHeight;
const targetHeight = screenHeight + 127; // Increase the height by 127 pixels (adjust as needed)
margin-top:-1px;
video.style.width = 'auto';
video.style.height = `${targetHeight}px`;
}
border-radius: 100%;
document.documentElement.requestFullscreen();
} else {
// Restore the original video dimensions
video.style.width = video.dataset.originalWidth;
video.style.height = video.dataset.originalHeight;
background-color: red;
document.exitFullscreen();
}
}
}
border-style: none;
cursor: pointer;
-webkit-appearance: none; /* Remove default appearance for Chrome, Safari and Opera */
-moz-appearance: none; /* Remove default appearance for Firefox */
appearance: none; /* Remove default appearance for Edge */
// Function to hide the control div with a fade-out effect
function showControlDiv(miraxTheme) {
miraxTheme.style.opacity = 1;
miraxTheme.style.transition = 'opacity 0.3s';
}
}
// Function to check for inactivity and hide the control div
function checkForInactivity(miraxPlayer, miraxTheme) {
let hideTimer;
function onMouseMove() {
// Mouse is moving, show the control div with a fade-in effect
miraxTheme.style.opacity = 0;
miraxTheme.style.transition = 'opacity 0.3s';
progress::-moz-range-thumb {
// Reset the hide timer
clearTimeout(hideTimer);
width: 11px;
// Set a new timer to hide the control div after 7 seconds of inactivity
hideTimer = setTimeout(() => {
showControlDiv(miraxTheme);
}, 7000); // 7000 milliseconds (7 seconds)
}
height: 11px;
function onMouseOver(event) {
// Mouse is over the player, check for inactivity
clearTimeout(hideTimer);
margin-top:-1px;
// Get the height of the viewport
const viewportHeight = window.innerHeight;
border-radius: 100%;
// Define the new threshold (e.g., 200 pixels) from the bottom to trigger the control div
const threshold = 200;
background-color: red;
// Calculate the distance from the mouse pointer to the bottom of the viewport
const distanceToBottom = viewportHeight - event.clientY;
const distanceToTop = viewportHeight - event.clientX;
border-style: none;
cursor: pointer;
// Check if the mouse pointer is within the threshold from the bottom
if (distanceToBottom <= threshold) {
// Mouse is near the wide bottom part, keep showing the control div
miraxTheme.style.opacity = 0;
miraxTheme.style.transition = 'opacity 0.3s';
}
-webkit-appearance: none; /* Remove default appearance for Chrome, Safari and Opera */
-moz-appearance: none; /* Remove default appearance for Firefox */
if (distanceToTop <= threshold) {
// Mouse is near the wide bottom part, keep showing the control div
miraxTheme.style.opacity = 0;
miraxTheme.style.transition = 'opacity 0.3s';
}
appearance: none; /* Remove default appearance for Edge */
}
}
function onMouseOut() {
// Mouse is out of the player, check for inactivity and hide the control div
showControlDiv(miraxTheme);
}
miraxPlayer.addEventListener('mousemove', onMouseMove);
miraxPlayer.addEventListener('mouseover', onMouseOver);
miraxPlayer.addEventListener('mouseout', onMouseOut);
// Initially hide the control div
miraxTheme.style.opacity = 0;
miraxTheme.style.transition = 'opacity 0.3s';
}

@@ -2679,151 +1556,239 @@

// Add an event listener to handle fullscreen change events
document.addEventListener('fullscreenchange', () => {
if (document.fullscreenElement === document.documentElement) {
// Mirax player container is in fullscreen mode, update your UI here
// You can modify the player's CSS or perform other actions
}
document.body.style.overflow = 'hidden'; // Prevent scrolling
document.documentElement.style.backgroundColor = '#000'; // Set background color
document.body.style.margin = '0'; // Remove body margin
document.body.style.padding = '0'; // Remove body padding
document.documentElement.style.margin = '0'; // Remove html margin
document.documentElement.style.padding = '0'; // Remove html padding
`;
inputProgressBar.appendChild(document.createTextNode(inputProgressBarStyle));
const miraxPlayer = document.querySelector('.mirax-player');
const miraxTheme = document.querySelector('.mirax-theme');
// Call the function to set up event listeners for inactivity handling
checkForInactivity(miraxPlayer, miraxTheme);
const inputPlayerClip = document.createElement('style');
document.head.appendChild(inputPlayerClip);
const inputPlayerClipStyle = `
.mirax-player {
min-width: 350px;
max-width: 100%;
width: 100%;
height: auto;
min-height: 100px;
max-height: 100%;
background-color: #000000;
margin: 0 auto;
}
/* Initially hide the control div */
.mirax-theme {
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1;
margin: 0 auto;
position: relative;
width: 100%;
height: 20px;
min-width: 350px;
max-width: 95%;
margin-top: -44px;
bottom: 0;
left: 10;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
padding-top: 5px;
padding-bottom: 5px;
display: flex;
justify-content: space-between;
align-items: center;
transition: opacity 10s;
}
.player-selector {
margin: 0 auto;
width: 100%;
max-width: 100%;
position: relative;
text-align: center;
}
`;
inputPlayerClip.appendChild(document.createTextNode(inputPlayerClipStyle));
//**********************************************//
//
playerDiv.classList.add('fullscreen-mode');
} else {
// Mirax player container exited fullscreen mode, update your UI here
// Restore the player's original UI
// Double Click Fullscreen
//
playerDiv.classList.remove('fullscreen-mode');
//*********************************************//
const inputPlayerClip = document.createElement('style');
document.head.appendChild(inputPlayerClip);
const inputPlayerClipStyle = `
.mirax-player {
min-width:350px;
max-width: ${dynamicWidth + 400}px;
width: 100%; /* This ensures the video fills its container while respecting max-width */
height: auto; /* This maintains the video's aspect ratio */
min-height:100px;
max-height:450px;
background-color: #000000;
margin: 0 auto;
}
/* Hide the control div by default */
.mirax-theme {
diplay: block;
opacity: 1;
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
display: block;
margin: 0 auto;
position: relative;
width: 95%;
height: 20px;
min-width:350px;
max-width: 95%;
margin-top:-44px;
bottom: 0;
left: 10;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
padding-top:5px;
padding-bottom:5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.player-selector {
margin: 0 auto;
width: 100%;
max-width: ${dynamicWidth}px;
position: relative;
float: ${dynamicFloat};
text-align: center;
}
`;
inputPlayerClip.appendChild(document.createTextNode(inputPlayerClipStyle));
videoClip.addEventListener('dblclick', toggleFullscreen);
//______________________________________________________________________
//**********************************************//
//
// Fullscreen Button
document.body.style.overflow = ''; // Restore scrolling
document.documentElement.style.backgroundColor = ''; // Restore background color
document.body.style.margin = ''; // Restore body margin
document.body.style.padding = ''; // Restore body padding
document.documentElement.style.margin = ''; // Restore html margin
document.documentElement.style.padding = ''; // Restore html padding
//
//*********************************************//
}
});
const fullscreenButton = document.createElement('mirax');
fullscreenButton.className = 'fullscreen';
controlDiv.appendChild(fullscreenButton);
fullscreenButton.addEventListener('click', toggleFullscreen);
function toggleFullscreen() {
if (videoClip.requestFullscreen) {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
videoClip.requestFullscreen();
}
}
}
}
}
/* # Mirax Player core license
Mirax Player is released under the MIT license:
MIT License
Copyright (c) [2023-present] [Demjhon Silver]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
export default miraxPlayer;

@@ -7,6 +7,9 @@

// Define the content string
const content_backward = "\\0279C";
const content_play = "\\27A4";
const content_forward = "\\0279C";
const content_pip = "\\021F1";
const content_fullscreen = "\\02752";
const content_backward = "\\27A4";
const content_play = "\\25B6";
const content_forward = "\\27A4";
const content_pause = "|" + " " + "|";
const content_speaker = "\\1F508";
const content_pip = "\\0393";

@@ -18,23 +21,5 @@

.speakerTrapezoid {
position: absolute;
right:-25px;
background: none;
margin-top:13px;
}
.speakerTrapezoid::before {
content: "";
width: 50px; /* Adjust the width and height as needed */
height: 50px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' width='50' height='50'%3E%3Crect x='5' y='16' width='5' height='16' fill='%23FFFFFF' /%3E%3Cpolygon points='10,19 30,9 30,39 10,29' fill='%23FFFFFF' /%3E%3C/svg%3E");
font-size: 15px;
appearance: none;
display: inline-block; /* Make sure it's an inline-block or block element */
}
.play-button {

@@ -62,9 +47,6 @@ position: absolute;

.play-button.pause::before {
content: "";
width: 30px; /* Adjust the width as needed */
height: 30px; /* Adjust the height as needed */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' width='30' height='30'%3E%3Crect x='0' y='40' width='10' height='35' fill='%23FFFFFF' /%3E%3Crect x='23' y='40' width='10' height='35' fill='%23FFFFFF' /%3E%3C/svg%3E");
font-size: 12px;
content: "${content_pause}";
color:white;
font-size:12px;
appearance: none;
display: inline-block; /* Make sure it's an inline-block or block element */
}

@@ -77,4 +59,2 @@

@@ -136,5 +116,5 @@ .play-button:hover {

right: 0;
margin-right:75px;
margin-right:73px;
top:0;
margin-top:-45px;
margin-top:-34px;
width:50px;

@@ -241,4 +221,20 @@ height: 3px;

/* .speaker-icon {
position: absolute;
float: right;
margin-top:-25px;
margin-left:32px;
}
.speaker-icon::before {
position: absolute;
content: "${content_speaker}";
font-size: 17px;
} */
.current-time {

@@ -269,7 +265,7 @@ position: absolute;

progress::-webkit-progress-value {
background-color: rgba(255, 255, 255, 0.8);
background-color: rgba(45, 85, 255, 0.9);
}
progress[value]::-moz-progress-bar {
background-color: rgba(255, 255, 255, 0.8);
background-color: rgba(45, 85, 255, 0.9);

@@ -289,7 +285,17 @@ }

.pip-button {
min-width:20px;
width: 100%;
max-width: 30px;
position: absolute;
right:54px;
background: none;
font-size:15px;
right:0;
margin-top: 4px;
margin-right:54px;
height: 20px;
background: none;
color: #fff;
border-style: none;
border-radius: 0;
cursor: pointer;
transition: color 0.3s ease;
font-size:15px;
}

@@ -300,3 +306,3 @@

content: "${content_pip}";
font-size:15px;
}

@@ -309,8 +315,17 @@

.fullscreen {
min-width:20px;
width: 100%;
max-width: 30px;
position: absolute;
right:5px;
background: none;
font-size:15px;
margin-right:5px;
right:0;
height: 20px;
background: none;
color: #fff;
border-style: none;
border-radius: 0;
cursor: pointer;
transition: color 0.3s ease;
font-size:15px;
}

@@ -322,17 +337,17 @@

.fullscreen::before {
content: "${content_fullscreen}";
.fullscreen::before {
color: #ffffff;
cursor: pointer;
content: "";
width: 12px; /* Adjust the width as needed */
height: 12px; /* Adjust the height as needed */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' width='12' height='12'%3E%3Crect x='0' y='0' width='100' height='100' fill='%23FFFFFF' /%3E%3Crect x='12' y='12' width='70' height='70' fill='%23818589' /%3E%3C/svg%3E");
font-size: 12px;
appearance: none;
display: inline-block; /* Make sure it's an inline-block or block element */
}
/* Style the text elements */

@@ -380,22 +395,8 @@ .video-text, .input-text {

const mediaQuery = `
@media (max-width: 840px) {
@media (max-width: 740px) {
/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
width: 100%;
max-width: 95%;
min-width: 300px;
height: 30px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
display: none;
}

@@ -406,22 +407,19 @@

.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
display: block;
margin: 0 auto;
position: relative;
width: 95%;
height: 20px;
max-width:96%;
margin-top:-44px;
bottom: 0;
left: 10;
color: #fff;
padding-top:5px;
padding-bottom:5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.player-selector {
margin: auto 0 !important;
margin-top:20px !important;
width:auto;
max-width: 95.90% !important;
margin-left:10px !important;
}
.mirax-player {
margin-right:-10px !important;
}
}

@@ -439,3 +437,3 @@ `;

const mediaQuery2 = `
@media (max-width: 690px) {
@media (max-width: 540px) {

@@ -452,60 +450,5 @@

/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
width: 100%;
max-width: 95%;
min-width: 300px;
height: 30px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
}
.player-selector {
margin: auto 0 !important;
margin-top:15px !important;
width:auto;
max-width: 94.90% !important;
margin-left:10px !important;
}
.mirax-player {
margin-right:-10px !important;
}
.play-button {
margin-left:0px;
}
.backward-button {
left:40%;
}
.forward-button {
left: 59%;
}
}

@@ -515,208 +458,1 @@ `;

miraxStyleMediaQuery2.appendChild(document.createTextNode(mediaQuery2));
const miraxStyleMediaQuery3 = document.createElement('style');
document.head.appendChild(miraxStyleMediaQuery3);
// Define the media query and its associated CSS rules
const mediaQuery3 = `
@media (max-width: 500px) {
.video-text, .input-text {
background-size: 50px 50px;
width:100%;
max-width:240px;
min-height:110px;
height: auto;
max-height:100px;
}
/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
width: 90%;
max-width: 90%;
min-width: 250px;
height: 30px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
}
.player-selector {
margin: auto 0 !important;
margin-top:10px !important;
width:auto;
max-width: 94.90% !important;
margin-left:10px !important;
}
.mirax-player {
margin-right: 5px !important;
}
.play-button {
margin-left:0px;
}
.backward-button {
left:40%;
}
.forward-button {
left: 59%;
}
}
`;
miraxStyleMediaQuery3.appendChild(document.createTextNode(mediaQuery3));
const miraxStyleMediaQuery4 = document.createElement('style');
document.head.appendChild(miraxStyleMediaQuery4);
// Define the media query and its associated CSS rules
const mediaQuery4 = `
@media (max-width: 360px) {
/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
width: 60%;
max-width: 70%!important;
min-width: 250px;
height: 30px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
}
.backward-button {
left:42%;
}
.forward-button {
left: 56%;
}
.mirax-player {
min-width:200px;
max-width: 300px !important;
width: 100%;
}
}
`;
miraxStyleMediaQuery4.appendChild(document.createTextNode(mediaQuery4));
const miraxStyleMediaQuery5 = document.createElement('style');
document.head.appendChild(miraxStyleMediaQuery5);
// Define the media query and its associated CSS rules
const mediaQuery5 = `
@media (max-width: 350px) {
/* Hide the control div by default */
.mirax-theme {
opacity: 0; /* Start with 0 opacity */
transition: opacity 0.3s; /* Use opacity for a smooth transition */
position: absolute;
bottom: 20px;
width: 100%;
max-width: 100%;
min-width: 230px;
height: 30px;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Adjust to perfectly center */
}
/* Show the control div when hovering over the video or itself */
.mirax-player:hover + .mirax-theme,
.mirax-theme:hover {
opacity: 1; /* Change opacity to 1 on hover to make it visible */
}
.backward-button {
left:42%;
}
.forward-button {
left: 58%;
}
}
`;
miraxStyleMediaQuery5.appendChild(document.createTextNode(mediaQuery5));

@@ -1,5 +0,5 @@

//index.js - This is package's entry point
//index.js - This is your package's entry point
export { default as embed } from './dist/miraxEmbedder';
export { default as miraxPlayer } from './dist/MiraxPlayer';
export { default as miraxEmbed } from './dist/miraxEmbedder';

@@ -6,0 +6,0 @@

@@ -6,31 +6,15 @@ // mirax-player.d.ts

// Type for the VideoEmbed function
type VideoEmbed = (
selector: HTMLDivElement | null
) => void;
// Type for the Video object built-in typescript
type Video = {
width?: number;
height?: number;
autoplay?: boolean;
fullscreen?: boolean;
controls?: boolean;
loop?: boolean;
videoUrl: string;
videoClass: string;
};
// Type for the VideoPlayer function
type VideoPlayer = (
videoClip: HTMLVideoElement
) => void;
// Type for the VideoEmbed function
type VideoEmbed = (
video: any, container?: HTMLElement
) => void;
// Type for the VideoPlayer function
type VideoPlayer = (
videoClip: HTMLVideoElement
) => void;
// Export the VideoEmbed & VideoPlayer type
// Export the VideoEmbed and VideoPlayer types
export const embed: VideoEmbed;
export const miraxPlayer: VideoPlayer;
}
{
"name": "mirax-player",
"version": "6.2.0",
"description": "Mirax Player is a free video player for React, Vue, Angular, and Svelte that can embed videos from platforms like Facebook, TikTok, YouTube/Shorts, Twitter, Vimeo and Dailymotion.",
"version": "6.3.0",
"description": "Mirax Player is a free video player for React, Vue, Angular, and Svelte that can embed videos from platforms like TikTok, YouTube/Shorts, Twitter, Vimeo and Dailymotion.",
"main": "index.js",
"types": "mirax-player.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {

@@ -17,3 +20,2 @@ "type": "git",

"embed video",
"facebook",
"youtube",

@@ -24,3 +26,2 @@ "vimeo",

"twitter",
"shorts",
"javascript",

@@ -33,5 +34,2 @@ "typescript",

],
"dependencies": {
"aziwork": "^1.0.0"
},
"author": "Demjhon Silver",

@@ -38,0 +36,0 @@ "license": "MIT",

@@ -9,11 +9,16 @@ <p align="center">

[![npm version](https://img.shields.io/npm/v/mirax-player.svg?logo=npm&style=flat-square&label=Latest&color=blue)](https://www.npmjs.com/package/mirax-player)
![Build Status](https://img.shields.io/badge/Build-Passing-brightgreen?style=flat-square)
![Written](https://img.shields.io/badge/JavaScript-blue?logo=javascript&label=Written&style=flat-square&color=FDDA0D)
![Downloads](https://img.shields.io/npm/dt/mirax-player.svg?&style=flat-square&label=Downloads&color=orange)
[![License](https://img.shields.io/npm/l/mirax-player.svg?style=flat-square&label=License&color=green)](https://github.com/demjhonsilver/mirax-player/blob/main/LICENSE.md)
![Written](https://img.shields.io/badge/JavaScript-blue?logo=javascript&label=Supports&style=flat-square&color=FDDA0D)
![Written](https://img.shields.io/badge/TypeScript-blue?logo=typescript&label=Supports&style=flat-square&color=blue)
![Downloads](https://img.shields.io/npm/dt/mirax-player.svg?style=flat-square&label=DOWNLOADS&color=brightgreen)
[![License](https://img.shields.io/npm/l/mirax-player.svg?style=flat-square&label=LICENSE&color=green)](https://github.com/demjhonsilver/mirax-player/blob/main/LICENSE.md)
</div>
</div>
<p align="center">

@@ -23,4 +28,2 @@ <img src="https://raw.githubusercontent.com/demjhonsilver/mirax-player/main/img/theme1.png"/>

---------------------

@@ -36,8 +39,2 @@

- [Embed Video](#embed-video)
- [TypeScript](#typescript)
- [Embed Css](#embed-css)
- [React](#react)
- [Vue](#vue)
- [Angular](#angular)
- [Svelte](#svelte)
- [Video Player](#video-player)

@@ -51,6 +48,6 @@ - [CSS Player](#css-player)

Mirax Player is a free video player for React, Vue, Angular, and Svelte that can embed videos from platforms like Facebook, TikTok, YouTube/Shorts, Twitter, Vimeo and Dailymotion. This library package enables you to dynamically embed videos from any video site, using any URL you like, and as many videos as you need.
Mirax Player is a free video player for React, Vue, Angular, and Svelte that can embed videos from platforms like TikTok, YouTube/Shorts, Twitter, Vimeo and Dailymotion. This library package enables you to set any URL once within a single embed code tag and dynamically embed videos from any video sites.
Frameworks / Libraries | Tested versions
Frameworks / Library | Tested versions
------ | -------- |

@@ -65,39 +62,37 @@ ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) | 18 & above

## Release-notes
Version 6.2.0
Major Changes:
Version 6
- The Mirax video player has been revised.
- The Mirax embed feature is now easier to use.
- The Mirax player can embed multiple videos.
- The embed TypeScript versions are available. [See TypeScript](#typescript)
Major changes:
Minor Changes:
- Mirax tags become Mirax props."
- useRef, ref, and element are based on HTMLDivElement, which has been removed."
- The class names for the player and embed are more aligned with naming conventions."
- The destructuring syntax becomes straightforward for named exports like { embed } and { player }.
v6.2.0
- The progress bar for video player is wider and the default color is white.
- The speed option panel is getting lower.
Minor changes:
v6.1.0
- Examples for React embedding are based on named exports.
- Adding a dependency from Aziwork.
6.3.0
- The shortcut key for playing videos will be Ctrl + Space for video player
6.2.0
- Revised data-mirax-embed to data-e-."
Patch Changes:
v6.1.2
Patch changes:
- Margin added to the Mirax video player for responsive dimensions.
- Progress bar move to the top
v6.1.1
-------
## Features
- The Aziwork package has been updated to version 1.0.0.
## Features
- This video player supports both TypeScript and JavaScript, making it developer-friendly.
- Easy to use and responsive.
- Capable of embedding one or many videos from platforms like Facebook, TikTok, YouTube, YouTube Shorts, Twitter, Dailymotion and Vimeo.
- Supports playing videos in both portrait and landscape orientations.
- Set up once, everything is flexible.
- Can embed videos like TikTok, YouTube, YouTube Shorts, Twitter, Vimeo and Dailymotion.
- Capable of playing videos (Portrait or Landscape).
- Customizable color themes.
- Supports PIP (Picture-in-Picture).
-------------

@@ -114,8 +109,9 @@ ## Installation

![Facebook](https://img.shields.io/badge/Facebook-%231877F2.svg?style=for-the-badge&logo=Facebook&logoColor=white)
![Twitter](https://img.shields.io/badge/Twitter-%231DA1F2.svg?style=for-the-badge&logo=Twitter&logoColor=white)
![YouTube](https://img.shields.io/badge/YouTube-%23FF0000.svg?style=for-the-badge&logo=YouTube&logoColor=white)
![TikTok](https://img.shields.io/badge/TikTok-%23000000.svg?style=for-the-badge&logo=TikTok&logoColor=white)
![Vimeo](https://camo.githubusercontent.com/2026999d43e099c9c835757e3d2f5f8c574efad153f4e3d5143914223e9cbc24/68747470733a2f2f613131796261646765732e636f6d2f62616467653f6c6f676f3d76696d656f)
![Dailymotion](https://a11ybadges.com/badge?logo=dailymotion)
Logo | Sites | Source type | Docs.
------ | -------- | --------- | ---------- |
![YouTube](https://img.shields.io/badge/YouTube-%23FF0000.svg?style=for-the-badge&logo=YouTube&logoColor=white) | YouTube / Shorts | Iframe Api | https://developers.google.com/youtube/iframe_api_reference
![Vimeo](https://camo.githubusercontent.com/2026999d43e099c9c835757e3d2f5f8c574efad153f4e3d5143914223e9cbc24/68747470733a2f2f613131796261646765732e636f6d2f62616467653f6c6f676f3d76696d656f) | Vimeo | Player SDK | https://developer.vimeo.com/player/sdk
![TikTok](https://img.shields.io/badge/TikTok-%23000000.svg?style=for-the-badge&logo=TikTok&logoColor=white) | TikTok | oEmbed API | https://developers.tiktok.com/doc/embed-videos/
![Dailymotion](https://a11ybadges.com/badge?logo=dailymotion) | Dailymotion | oEmbed API | https://developers.dailymotion.com/player/#player-oembed
![Twitter](https://img.shields.io/badge/Twitter-%231DA1F2.svg?style=for-the-badge&logo=Twitter&logoColor=white) | Twitter / X | JavaScript API | https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/set-up-twitter-for-websites
--------

@@ -125,117 +121,51 @@

Attributes | Functionality | Type | Required |
Mirax embed props | Functionality | Type | Required |
------ | -------- | -------- | ----------
`width` | dynamic width | number | optional
`height` | dynamic height | number |optional
`fullscreen` | enable fullscreen | boolean | optional
`controls` | enable controllers | boolean | optional
`autoplay` | enable autoplay | boolean | optional
`loop` | enable loop | boolean | optional
`videoClass` | set any classname | string | yes
`videoUrl` | video address, url/links | string | yes
`mirax-embed` | responsiveness | any | yes
`data-e-width` | dynamic width | integer | yes
`data-e-height` | dynamic height | integer | yes
`data-e-fullscreen` | enable fullscreen | boolean | optional (true false)
`data-e-controls` | enable controllers | boolean | optional (true false )
`data-e-autoplay` | enable autoplay | boolean | optional (true false)
`data-e-loop` | enable loop | boolean | optional (true false)
`data-e-url` | video address, url/links | any | yes
---------
## TypeScript
![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)
- located at repository files
```html
mirax-player/
|-- src/
| |-- angular/
| |-- react/TypeScriptEmbed.md
| |-- svelte/TypeScriptEmbed.md
| |-- vue/TypeScriptEmbed.md
src/react/TypeScriptPlayer.md
src/react/TypeScriptEmbed.md
src/vue/TypeScriptPlayer.md
src/vue/TypeScriptEmbed.md
src/svelte/TypeScriptPlayer.md
src/svelte/TypeScriptEmbed.md
```
## Embed-css
You can add your own css set-up: <!-- You can rename, change color, resize, positioning etc. -->
You may apply to app.css or index.css or any css file.
This is sample only, you can rename, recreate, and do something:
```css
.embed-youtube-one-clip {
display: flex;
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
border: 2px solid orange;
width: 100%;
max-width: 640px;
margin: auto; /* Center the entire container horizontally */
}
```
For more css embed video styles:
- located at css.md
```html
mirax-player/
|-- src/css-embed/css.md (including Angular css)
```
-----------
If you want sample code for embed multiple videos?
-----
Located at repository files ( EMBED MANY VIDEOS HERE)
```
mirax-player/
|-- src/
| |-- angular/TypeScriptEmbed.md
| |-- react/JavaScriptEmbed.md
| |-- svelte/JavaScriptEmbed.md
| |-- vue/JavaScriptEmbed.md
```
------
Use Google chrome as much as possible to load more videos properly.
------------
Recommended web browser for local test:
-----
![Google Chrome](https://img.shields.io/badge/Google%20Chrome-4285F4?style=for-the-badge&logo=GoogleChrome&logoColor=white)
--------
Reminder:
- Don't forget to restart your server.
------------
## React
```jsx
import { useEffect } from 'react';
# React embed
```js
import React, { useEffect } from "react";
import { embed } from 'mirax-player';
export const ExampleComponent = () => {
const ExampleComponent = () => {
useEffect(() => {
embed([
{
width: 640,
height: 360,
autoplay: true,
fullscreen: false,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=oEXFMGK7IC0',
videoClass: 'embed-youtube-one-clip'
}
])
});
embed("mirax-embed");
}, []);
return (
<>
<div className="embed-youtube-one-clip"></div>
</>
<div className="mirax-embed"
data-e-width="640" // 800 x 450 or 1000 x 562.5
data-e-height="360"
data-e-autoplay="false" // for autoplay set true or remove this props
data-e-url="https://vimeo.com/217499569">
</div>
);
};
export default ExampleComponent;
```
## Vue
```js
# Vue embed
```js
<template>
<div>
<div class="embed-youtube-one-clip"></div>
<div class="mirax-embed"
data-e-width="640" // 800 x 450 or 1000 x 562.5
data-e-height="360"
data-e-autoplay="false" // for autoplay set true or remove this props
data-e-url="https://vimeo.com/217499569">
</div>

@@ -245,31 +175,18 @@ </template>

<script>
import { onMounted } from 'vue';
import { onMounted } from "vue";
import { embed } from 'mirax-player';
export default {
name: 'ExampleComponent',
setup() {
onMounted(() => {
embed([
{
width: 640,
height: 360,
autoplay: true,
fullscreen: false,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=oEXFMGK7IC0',
videoClass: 'embed-youtube-one-clip'
}
])
embed('mirax-embed');
});
return {};
},
}
};
</script>
```
## Angular
# Angular embed
```ts
import { Component, AfterViewInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { embed } from 'mirax-player';

@@ -279,45 +196,26 @@

selector: 'app-example',
template: `
<div class="embed-youtube-one-clip"></div>
`,
styleUrls: ['./example.component.css'],
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements AfterViewInit {
ngAfterViewInit() {
embed([
{
width: 640,
height: 360,
autoplay: true,
fullscreen: false,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=oEXFMGK7IC0',
videoClass: 'embed-youtube-one-clip'
}
]);
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit(): void {
embed('mirax-embed');
}
}
}
```
For Angular css:
---
example.component.html
[Angular embed Css](#embed-css)
```css
::ng-deep .embed-youtube-one-clip {
display: flex;
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
border: 2px solid orange;
width: 100%;
max-width: 640px;
margin: auto; /* Center the entire container horizontally */
}
-------------
```html
<div class="mirax-embed"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false"
data-e-url="https://vimeo.com/217499569">
</div>
```
## Svelte
```js
# Svelte embed
```js
<script>

@@ -328,26 +226,21 @@ import { onMount } from 'svelte';

onMount(() => {
embed([
{
width: 640,
height: 360,
autoplay: true,
fullscreen: false,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=oEXFMGK7IC0',
videoClass: 'embed-youtube-one-clip'
}
]);
embed('mirax-embed');
});
</script>
<div>
<div class="embed-youtube-one-clip"></div>
<div class="mirax-embed"
data-e-width="640" // 800 x 450 or 1000 x 562.5
data-e-height="360"
data-e-autoplay="false" // for autoplay set true or remove this props
data-e-url="https://vimeo.com/217499569">
</div>
```
-----------------
## Video-player
Player Attributes | Functionality |Type | Required |
Mirax player props | Functionality |Type | Required |
------ | -------- | ----------- | ----------
`player-selector` | responsiveness | any| yes
`data-player-width` | dynamic width | number | yes
`data-player-width` | dynamic width | integer | yes
`data-player-float` | dynamic alignment | string |optional

@@ -379,10 +272,10 @@ `data-player-theme` | player color | any | optional

```js
import { useEffect, useRef } from "react";
import React, { useEffect, useRef } from "react";
import { miraxPlayer } from 'mirax-player';
export const ExampleComponent = () => {
const ExampleComponent = () => {
const playerDiv = useRef(null);
useEffect(() => {
miraxPlayer(playerDiv.current);
});
},[]);
return (

@@ -397,2 +290,3 @@ <div className="player-selector">

};
export default ExampleComponent;
```

@@ -403,3 +297,3 @@ # Vue video player

<div class="player-selector">
<video ref="playerDiv"
<video ref="videoPlayer"
class="mirax-player"

@@ -418,8 +312,8 @@ data-player-width="800"

setup() {
const playerDiv = ref(null);
const videoPlayer = ref(null);
onMounted(() => {
miraxPlayer(playerDiv.value);
miraxPlayer(videoPlayer.value);
});
return {
playerDiv
videoPlayer
};

@@ -444,3 +338,3 @@ }

export class ExampleComponent implements AfterViewInit {
@ViewChild('playerDiv', { static: true }) playerDiv!: ElementRef<HTMLVideoElement>;
@ViewChild('videoPlayer', { static: true }) videoPlayer!: ElementRef<HTMLVideoElement>;
ngAfterViewInit(): void {

@@ -450,3 +344,3 @@ this.initializemiraxPlayer();

initializemiraxPlayer() {
miraxPlayer(this.playerDiv.nativeElement);
miraxPlayer(this.videoPlayer.nativeElement);
}

@@ -461,3 +355,3 @@ }

<div class="player-selector">
<video #playerDiv
<video #videoPlayer
class="mirax-player"

@@ -475,5 +369,5 @@ data-player-width="800"

let playerDiv;
let videoPlayer;
onMount(() => {
miraxPlayer(playerDiv);
miraxPlayer(videoPlayer);
});

@@ -483,3 +377,3 @@ </script>

<div class="player-selector">
<video bind:this={playerDiv} class="mirax-player"
<video bind:this={videoPlayer} class="mirax-player"
data-player-width="800"

@@ -543,3 +437,2 @@ src="clip.mp4">

## License

@@ -546,0 +439,0 @@

@@ -1,74 +0,15 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md (including Angular css)
Use Google chrome as much as possible to load more videos properly.
```ts
import { Component, AfterViewInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { embed } from 'mirax-player';
interface VideoConfig {
width?: number;
height?: number;
autoplay?: boolean;
fullscreen?: boolean;
controls?: boolean;
videoUrl: string;
videoClass: string;
}
@Component({
selector: 'app-example',
template: `
<div class="embed-tiktok"></div>
<div class="embed-twitter"></div>
<div class="embed-youtube"></div>
<div class="embed-facebook"></div>
<div class="embed-facebook2"></div>
`,
styleUrls: ['./example.component.css'],
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements AfterViewInit {
videos: VideoConfig[] = [
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
];
ngAfterViewInit(): void {
embed(this.videos);
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit(): void {
embed('mirax-embed');
}
}
```

@@ -1,63 +0,19 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```jsx
import { useEffect } from 'react';
```js
import React, { useEffect } from "react";
import { embed } from 'mirax-player';
export const ExampleComponent = () => {
const videos = [
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
];
const ExampleComponent = () => {
useEffect(() => {
embed(videos);
});
embed("mirax-embed");
}, []);
return (
<>
<div className="embed-tiktok"></div>
<div className="embed-twitter"></div>
<div className="embed-youtube"></div>
<div className="embed-facebook"></div>
<div className="embed-facebook2"></div>
</>
<div className="mirax-embed"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false" // for autoplay set true or remove this props (data-e-autoplay="false")
data-e-url="https://vimeo.com/217499569">
</div>
);
};
export default ExampleComponent;
```

@@ -1,73 +0,20 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```ts
import { useEffect } from 'react';
import React, { useEffect } from "react";
import { embed } from 'mirax-player';
interface VideoConfig {
width?: number;
height?: number;
autoplay?: boolean;
fullscreen?: boolean;
controls?: boolean;
videoUrl: string;
videoClass: string;
}
export const ExampleComponent: React.FC = () => {
const videos: VideoConfig[] = [
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok',
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter',
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube',
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook',
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2',
},
];
const ExampleComponent: React.FC = () => {
useEffect(() => {
embed(videos);
});
embed("mirax-embed");
}, []);
return (
<>
<div className="embed-tiktok"></div>
<div className="embed-twitter"></div>
<div className="embed-youtube"></div>
<div className="embed-facebook"></div>
<div className="embed-facebook2"></div>
</>
<div className="mirax-embed"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false" // for autoplay set true or remove this props (data-e-autoplay="false")
data-e-url="https://vimeo.com/217499569">
</div>
);
};
export default ExampleComponent;
```
```ts
import { useEffect, useRef } from "react";
import React, { useEffect, useRef } from "react";
import { miraxPlayer } from 'mirax-player';
interface ExampleComponentProps {
dataPlayerWidth?: number;
}
export const ExampleComponent: React.FC<ExampleComponentProps> = ({ dataPlayerWidth }) => {
const ExampleComponent: React.FC = () => {
const playerDiv = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
if (playerDiv.current) {
miraxPlayer(playerDiv.current);
}
}, [dataPlayerWidth]);
},[]);
return (
<div className="player-selector">
<video
className="mirax-player"
ref={playerDiv}
data-player-width={dataPlayerWidth || 800}
src="clip.mp4"
></video>
<video className="mirax-player" ref={playerDiv}
data-player-width="800"
src="clip.mp4">
</video>
</div>
);
};
export default ExampleComponent;
```

@@ -1,9 +0,1 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```js

@@ -14,49 +6,13 @@ <script>

const videos = [
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
];
onMount(() => {
embed(videos);
embed('mirax-embed');
});
</script>
<div>
<div class="embed-tiktok"></div>
<div class="embed-twitter"></div>
<div class="embed-youtube"></div>
<div class="embed-facebook"></div>
<div class="embed-facebook2"></div>
<div class="mirax-embed"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false"
data-e-url="https://vimeo.com/217499569">
</div>
```

@@ -1,9 +0,1 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```ts

@@ -13,60 +5,14 @@ <script lang="ts">

import { embed } from 'mirax-player';
interface VideoConfig {
width?: number;
height?: number;
autoplay?: boolean;
fullscreen?: boolean;
controls?: boolean;
videoUrl: string;
videoClass: string;
}
const videos: VideoConfig[] = [
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
];
onMount(() => {
embed(videos);
embed(embedDiv);
});
</script>
<div>
<div class="embed-tiktok"></div>
<div class="embed-twitter"></div>
<div class="embed-youtube"></div>
<div class="embed-facebook"></div>
<div class="embed-facebook2"></div>
<div class="mirax-player"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false"
data-e-url="https://vimeo.com/217499569">
</div>
```
```
```ts
<!-- YourComponent.svelte -->
<script lang="ts">

@@ -7,10 +6,6 @@ import { onMount } from 'svelte';

export let dataPlayerWidth: number | undefined;
let playerDiv: HTMLVideoElement | undefined;
let playerDiv: HTMLVideoElement | null;
onMount(() => {
if (playerDiv) {
miraxPlayer(playerDiv);
}
});

@@ -20,11 +15,8 @@ </script>

<div class="player-selector">
<video
class="mirax-player"
bind:this={playerDiv}
data-player-width={dataPlayerWidth || 800}
src="clip.mp4">
<video class="mirax-player" bind:this={playerDiv}
data-player-width="800"
src="clip.mp4">
<track kind="captions" src="" label="English" default>
</video>
</div>
```

@@ -1,17 +0,8 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```js
<template>
<div>
<div class="embed-tiktok"></div>
<div class="embed-twitter"></div>
<div class="embed-youtube"></div>
<div class="embed-facebook"></div>
<div class="embed-facebook2"></div>
<div class="mirax-embed"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false"
data-e-url="https://vimeo.com/217499569">
</div>

@@ -21,53 +12,14 @@ </template>

<script>
import { onMounted } from 'vue';
import { onMounted } from "vue";
import { embed } from 'mirax-player';
export default {
name: 'ExampleComponent',
setup() {
const videos = ([
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
]);
onMounted(() => {
embed(videos);
embed('mirax-embed');
});
return {
videos,
};
},
return {};
}
};
</script>
```

@@ -1,17 +0,8 @@

You can find the css styles for these embed videos
mirax-player/
|-- src/css-embed/css.md
Use Google chrome as much as possible to load more videos properly.
```ts
<template>
<div>
<div class="embed-tiktok"></div>
<div class="embed-twitter"></div>
<div class="embed-youtube"></div>
<div class="embed-facebook"></div>
<div class="embed-facebook2"></div>
<div class="mirax-embed" ref="embedDiv"
data-e-width="640"
data-e-height="360"
data-e-autoplay="false"
data-e-url="https://vimeo.com/217499569">
</div>

@@ -21,55 +12,9 @@ </template>

<script setup lang="ts">
import { onMounted } from 'vue';
import { onMounted } from "vue";
import { embed } from 'mirax-player';
const videos = <VideoConfig[]>([
{
videoUrl: 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
videoClass: 'embed-tiktok'
},
{
width: 300,
height: 600,
videoUrl: 'https://twitter.com/cheerfulclips/status/1677022600655175680',
videoClass: 'embed-twitter'
},
{
width: 640,
height: 360,
fullscreen: true,
controls: true,
videoUrl: 'https://www.youtube.com/watch?v=vBGiFtb8Rpw',
videoClass: 'embed-youtube'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook'
},
{
width: 318,
height: 180,
autoplay: false,
videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
videoClass: 'embed-facebook2'
},
]);
onMounted(() => {
embed(videos);
embed('mirax-embed');
});
interface VideoConfig {
width?: number;
height?: number;
autoplay?: boolean;
fullscreen?: boolean;
controls?: boolean;
videoUrl: string;
videoClass: string;
}
</script>
```
```ts
<template>
<div class="player-selector">
<video
class="mirax-player"
ref="playerDiv"
:data-player-width="dataPlayerWidth || 800"
src="clip.mp4"
>
<track kind="captions" src="" label="English" default />
<video class="mirax-player" ref="playerDiv"
data-player-width="800"
src="clip.mp4">
</video>

@@ -15,27 +11,12 @@ </div>

<script lang="ts">
import { ref, onMounted, defineProps } from 'vue';
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { miraxPlayer } from 'mirax-player';
export default {
props: {
dataPlayerWidth: Number,
},
setup() {
const playerDiv = ref<HTMLVideoElement | null>(null);
const props = defineProps(['dataPlayerWidth']);
const playerDiv = ref<HTMLVideoElement | null>(null);
onMounted(() => {
if (playerDiv.value) {
miraxPlayer(playerDiv.value);
}
});
return {
playerDiv,
props,
};
},
};
onMounted(() => {
miraxPlayer(playerDiv.value);
});
</script>
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc