me-vp
Version:
change the default style of the video player
237 lines (236 loc) • 19.1 kB
JavaScript
import VideoPlayerAbstract from "./abstract.js";
class VideoPlayer extends VideoPlayerAbstract {
constructor(container, src, width, skipTime, theme) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
let myTheme = {
color: "white",
backgroundColor: "black",
accent: "white",
};
super(src, container, width, skipTime, Object.assign(Object.assign({}, myTheme), theme));
this.count = 0;
this.createVideoContainer = () => {
let videoContainer = document.createElement("div");
videoContainer.style.position = "relative";
videoContainer.style.width = this.width;
return videoContainer;
};
this.createVideo = () => {
let video = document.createElement("video");
video.setAttribute("id", `myVideo123${this.count}`);
video.setAttribute("width", "100%");
video.volume = 0.1;
// video.controls = true;
video.innerHTML = `
<source src="${this.src}" type="video/mp4" />
`;
return video;
};
this.createControlContainer = () => {
let controlContainer = document.createElement("div");
controlContainer.style.position = "absolute";
controlContainer.style.width = "100%";
controlContainer.style.height = "100%";
controlContainer.style.top = "0";
controlContainer.style.display = "flex";
controlContainer.style.alignItems = "end";
return controlContainer;
};
this.createControl = () => {
let control = document.createElement("div");
control.style.height = "3.5rem";
control.style.padding = "0px 10px";
control.style.width = "100%";
control.style.display = "flex";
control.style.flexDirection = "column";
control.style.justifyContent = "space-between";
control.style.paddingBottom = "8px";
control.innerHTML = `
<div style="display:flex;justify-content:space-between;align-items:center;color:white">
<small id="currentTime${this.count}">00:00:00</small>
<input type="range" value=0 style="width:80%;height:3px;accent-color:${this.theme.color};" id="timeRange${this.count}"/>
<small id="durationTime${this.count}" >00:00:00</small>
</div>
<div style="width:100%;display:flex; align-items:center;justify-content:space-between;" >
<div style="width:155px;display:flex;align-items:center">
<div style="width:35px;cursor:pointer;opacity:.8" id="volume${this.count}">${this.icons.unMuted}</div>
<input type="range" max="1" step="0.1" value=0.1 style="width:100px;height:3px;accent-color:${this.theme.color};" id="volumeRange${this.count}"/>
</div>
<div style='display:flex ;width:100px;justify-content:space-between;align-items:center'>
<div style="cursor:pointer;opacity:.8" id="backStep${this.count}" title="-${this.skipTime}">${this.icons.backStep}</div>
<div style="cursor:pointer;opacity:.8" id="playToggle${this.count}">${this.icons.pause}</div>
<div style="cursor:pointer;opacity:.8" id="forwardStep${this.count}" title="+${this.skipTime}">${this.icons.forwardStep}</div>
</div>
<div style="width:155px;display:flex;align-items:center;justify-content:end">
<div style="width:35px;cursor:pointer;opacity:.8" id="fullScreen${this.count}">${this.icons.fullScreen}</div>
</div>
</div>
`;
return control;
};
this.createLoader = () => {
let loader = this.createControlContainer();
loader.innerHTML = `
${this.icons.spinner}
<style>
spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>`;
loader.style.display = "none";
loader.id = `loader${this.count}`;
return loader;
};
this.addEvents = () => {
let controlContainer = document.getElementById(`controlContainer${this.count}`);
let timeRange = document.querySelector(`input[id='timeRange${this.count}']`);
let video = document.querySelector(`video[id='myVideo123${this.count}']`);
let playToggle = document.querySelector(`div[id='playToggle${this.count}']`);
let durationTime = document.getElementById(`durationTime${this.count}`);
let currentTime = document.getElementById(`currentTime${this.count}`);
let loader = document.getElementById(`loader${this.count}`);
let volume = document.getElementById(`volume${this.count}`);
let volumeRange = document.querySelector(`input[id='volumeRange${this.count}']`);
let fullScreen = document.getElementById(`fullScreen${this.count}`);
let forwardStep = document.getElementById(`forwardStep${this.count}`);
let backStep = document.getElementById(`backStep${this.count}`);
video === null || video === void 0 ? void 0 : video.addEventListener("loadedmetadata", () => {
timeRange === null || timeRange === void 0 ? void 0 : timeRange.setAttribute("max", `${video === null || video === void 0 ? void 0 : video.duration}`);
if (durationTime)
durationTime.innerHTML = this.getTime(video.duration);
});
video === null || video === void 0 ? void 0 : video.addEventListener("timeupdate", () => {
if (timeRange) {
timeRange.value = `${video.currentTime}`;
}
if (currentTime)
currentTime.innerHTML = this.getTime(video.currentTime);
});
video === null || video === void 0 ? void 0 : video.addEventListener("play", () => {
if (playToggle)
playToggle.innerHTML = this.icons.pause;
});
video === null || video === void 0 ? void 0 : video.addEventListener("pause", () => {
if (playToggle)
playToggle.innerHTML = this.icons.play;
});
timeRange === null || timeRange === void 0 ? void 0 : timeRange.addEventListener("input", function () {
if (video === null || video === void 0 ? void 0 : video.currentTime)
video.currentTime = Number(this.value);
});
playToggle === null || playToggle === void 0 ? void 0 : playToggle.addEventListener("click", function () {
if (this.innerHTML.includes("play")) {
video === null || video === void 0 ? void 0 : video.play();
}
else {
video === null || video === void 0 ? void 0 : video.pause();
}
});
video === null || video === void 0 ? void 0 : video.addEventListener("waiting", () => loader === null || loader === void 0 ? void 0 : loader.setAttribute("style", "position: absolute; width: 100%; height: 100%; top: 0px; display: flex; align-items: end; "));
video === null || video === void 0 ? void 0 : video.addEventListener("playing", () => loader === null || loader === void 0 ? void 0 : loader.setAttribute("style", "display:none"));
controlContainer === null || controlContainer === void 0 ? void 0 : controlContainer.addEventListener("mouseout", function () {
this.style.opacity = "0";
});
controlContainer === null || controlContainer === void 0 ? void 0 : controlContainer.addEventListener("mouseover", function () {
this.style.opacity = "1";
});
volume === null || volume === void 0 ? void 0 : volume.addEventListener("click", () => {
if (volume.innerHTML.includes("unmuted")) {
volume.innerHTML = this.icons.muted;
if (volumeRange)
volumeRange.value = "0";
if (video)
video.volume = 0;
}
else {
volume.innerHTML = this.icons.unMuted;
if (volumeRange)
volumeRange.value = "0.1";
if (video)
video.volume = 0.1;
}
if (video)
video.muted = !volume.innerHTML.includes("unmuted");
});
volumeRange === null || volumeRange === void 0 ? void 0 : volumeRange.addEventListener("input", () => {
if (video)
video.volume = Number(volumeRange.value);
if ((video === null || video === void 0 ? void 0 : video.volume) == 0 && volume) {
volume.innerHTML = this.icons.muted;
video.muted = true;
}
if (video && (video === null || video === void 0 ? void 0 : video.volume) > 0 && volume) {
volume.innerHTML = this.icons.unMuted;
video.muted = false;
}
});
fullScreen === null || fullScreen === void 0 ? void 0 : fullScreen.addEventListener("click", () => {
video === null || video === void 0 ? void 0 : video.requestFullscreen();
});
forwardStep === null || forwardStep === void 0 ? void 0 : forwardStep.addEventListener("click", () => {
if (video && video.currentTime < video.duration)
video.currentTime = video.currentTime + Number(this.skipTime);
});
backStep === null || backStep === void 0 ? void 0 : backStep.addEventListener("click", () => {
if (video && video.currentTime > 0.1)
video.currentTime = video.currentTime - Number(this.skipTime);
});
//hover
playToggle === null || playToggle === void 0 ? void 0 : playToggle.addEventListener("mouseover", () => (playToggle.style.opacity = "1"));
playToggle === null || playToggle === void 0 ? void 0 : playToggle.addEventListener("mouseout", () => (playToggle.style.opacity = ".8"));
volume === null || volume === void 0 ? void 0 : volume.addEventListener("mouseover", () => (volume.style.opacity = "1"));
volume === null || volume === void 0 ? void 0 : volume.addEventListener("mouseout", () => (volume.style.opacity = ".8"));
fullScreen === null || fullScreen === void 0 ? void 0 : fullScreen.addEventListener("mouseover", () => (fullScreen.style.opacity = "1"));
fullScreen === null || fullScreen === void 0 ? void 0 : fullScreen.addEventListener("mouseout", () => (fullScreen.style.opacity = ".8"));
forwardStep === null || forwardStep === void 0 ? void 0 : forwardStep.addEventListener("mouseover", () => (forwardStep.style.opacity = "1"));
forwardStep === null || forwardStep === void 0 ? void 0 : forwardStep.addEventListener("mouseout", () => (forwardStep.style.opacity = ".8"));
backStep === null || backStep === void 0 ? void 0 : backStep.addEventListener("mouseover", () => (backStep.style.opacity = "1"));
backStep === null || backStep === void 0 ? void 0 : backStep.addEventListener("mouseout", () => (backStep.style.opacity = ".8"));
};
this.icons = {
pause: `<svg style="width:2rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_a = this.theme) === null || _a === void 0 ? void 0 : _a.accent}" d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm224-72l0 144c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-144c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0l0 144c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-144c0-13.3 10.7-24 24-24s24 10.7 24 24z"/></svg>`,
play: `<svg style="width:2rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, play Inc.--><path fill="${(_b = this.theme) === null || _b === void 0 ? void 0 : _b.accent}" d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c7.6-4.2 16.8-4.1 24.3 .5l144 88c7.1 4.4 11.5 12.1 11.5 20.5s-4.4 16.1-11.5 20.5l-144 88c-7.4 4.5-16.7 4.7-24.3 .5s-12.3-12.2-12.3-20.9l0-176c0-8.7 4.7-16.7 12.3-20.9z"/></svg>`,
spinner: `<svg style="width:50px;margin:auto ;animation: spin 2s linear infinite;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_c = this.theme) === null || _c === void 0 ? void 0 : _c.accent}" d="M304 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm0 416a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM48 304a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm464-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM142.9 437A48 48 0 1 0 75 369.1 48 48 0 1 0 142.9 437zm0-294.2A48 48 0 1 0 75 75a48 48 0 1 0 67.9 67.9zM369.1 437A48 48 0 1 0 437 369.1 48 48 0 1 0 369.1 437z"/></svg>`,
unMuted: `<svg style="width:1rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- unmuted !Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_d = this.theme) === null || _d === void 0 ? void 0 : _d.accent}" d="M533.6 32.5C598.5 85.2 640 165.8 640 256s-41.5 170.7-106.4 223.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C557.5 398.2 592 331.2 592 256s-34.5-142.2-88.7-186.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM473.1 107c43.2 35.2 70.9 88.9 70.9 149s-27.7 113.8-70.9 149c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C475.3 341.3 496 301.1 496 256s-20.7-85.3-53.2-111.8c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zm-60.5 74.5C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM301.1 34.8C312.6 40 320 51.4 320 64l0 384c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352 64 352c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l67.8 0L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3z"/></svg>`,
muted: `<svg style="width:1rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_e = this.theme) === null || _e === void 0 ? void 0 : _e.accent}" d="M301.1 34.8C312.6 40 320 51.4 320 64l0 384c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352 64 352c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l67.8 0L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zM425 167l55 55 55-55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-55 55 55 55c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-55-55-55 55c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l55-55-55-55c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z"/></svg>`,
fullScreen: `<svg style="width:1rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_f = this.theme) === null || _f === void 0 ? void 0 : _f.accent}" d="M344 0L488 0c13.3 0 24 10.7 24 24l0 144c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-87 87c-9.4 9.4-24.6 9.4-33.9 0l-32-32c-9.4-9.4-9.4-24.6 0-33.9l87-87L327 41c-6.9-6.9-8.9-17.2-5.2-26.2S334.3 0 344 0zM168 512L24 512c-13.3 0-24-10.7-24-24L0 344c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39 87-87c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8z"/></svg>`,
forwardStep: `<svg style="width:1rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_g = this.theme) === null || _g === void 0 ? void 0 : _g.accent}" d="M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416L0 96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241l0-145c0-17.7 14.3-32 32-32s32 14.3 32 32l0 320c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-145-11.5 9.6-192 160z"/></svg>`,
backStep: `<svg style="width:1rem" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.7.2 by - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="${(_h = this.theme) === null || _h === void 0 ? void 0 : _h.accent}" d="M267.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29l0-320c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160L64 241 64 96c0-17.7-14.3-32-32-32S0 78.3 0 96L0 416c0 17.7 14.3 32 32 32s32-14.3 32-32l0-145 11.5 9.6 192 160z"/></svg>`,
};
this.count = VideoPlayer.count++;
let startContainer = this.createControlContainer();
let controlContainer = this.createControlContainer();
let video = this.createVideo();
let videoContainer = this.createVideoContainer();
let control = this.createControl();
let loader = this.createLoader();
startContainer.style.background = "black";
startContainer.innerHTML = `
<div style="display:flex;justify-content:center;align-items:center;width:100%;height:100%">
${this.icons.play}
</div>`;
startContainer.addEventListener("click", () => {
startContainer.style.display = "none";
video.play();
});
controlContainer.id = `controlContainer${this.count}`;
control.style.backgroundImage = `linear-gradient(180deg, #ffffff00,rgba(0, 0, 0, 0.46), ${(_j = this.theme) === null || _j === void 0 ? void 0 : _j.backgroundColor})`;
controlContainer.append(control);
videoContainer.append(video);
videoContainer.append(controlContainer);
videoContainer.append(startContainer);
videoContainer.append(loader);
(_k = document.getElementById(this.container)) === null || _k === void 0 ? void 0 : _k.append(videoContainer);
this.addEvents();
}
getTime(time) {
let h = time / (60 * 60);
time = time % (60 * 60);
let m = time / 60;
let s = time % 60;
return `${h < 10 ? "0" + h.toFixed() : h.toFixed()}:${m < 10 ? "0" + m.toFixed() : m.toFixed()}:${s < 10 ? "0" + s.toFixed() : s.toFixed()}`;
}
}
VideoPlayer.count = 0;
export default VideoPlayer;