// gemini code
// In your Common.js
$(document).ready(function() {
// Find every native audio player generated by the wiki
$('audio').each(function() {
// Create your custom component
const myPlayer = document.createElement('audio-player');
// Transfer the source
myPlayer.setAttribute('track', $(this).attr('src'));
// Replace the native player with your custom one
$(this).replaceWith(myPlayer);
});
});
// audioplayer.js (pulled from website)
if (!customElements.get('audio-player')) {
class AudioPlayer extends HTMLElement {
connectedCallback() {
const song = this.getAttribute("song") || "";
const artist = this.getAttribute("artist") || "";
const src = this.getAttribute("track") || "";
const cover = this.getAttribute("artcover") || "";
const originalArtist =
this.getAttribute("originalartist") || "";
const originalSource =
this.getAttribute("originalsource") || "";
const ext = src.split(".").pop().toLowerCase();
let mime = "audio/mpeg";
if (ext === "wav") {
mime = "audio/wav";
}
this.innerHTML = `
<style>
.player {
display: flex;
width: 100%;
max-width: 500px;
min-height: 150px;
background: var(--box-color);
color: white;
border-radius: 12px;
overflow: hidden;
font-family: Arial, sans-serif;
}
.cover {
width: 40%;
object-fit: cover;
background-color: #333;
display: block;
}
.info {
width: 60%;
padding: 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 10px;
}
.meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.leftmeta,
.rightmeta {
display: flex;
flex-direction: column;
gap: 4px;
}
h3 {
margin: 0;
font-size: 16px;
}
p {
margin: 0;
font-size: 12px;
opacity: 0.7;
}
.credit {
font-size: 11px;
opacity: 0.6;
line-height: 1.4;
}
.controls {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
}
.playBtn {
width: 24px;
height: 24px;
background: var(--green-color);
border: none;
color: white;
padding: 3px 8px;
border-radius: 50px;
cursor: pointer;
flex-shrink: 0;
}
.playBtn:hover {
background: var(--green-hover);
}
.playBtn:active {
background: var(--green-active);
}
.seek {
-webkit-appearance: none;
appearance: none;
border-radius: 50px;
flex: 1;
background-color: #7e7e7e;
height: 7px;
min-width: 0;
}
.seek::-webkit-slider-thumb {
-webkit-appearance: none; /* Override default look */
appearance: none;
border-radius: 50px;
width: 15px;
height: 15px;
background: var(--green-color);
cursor: pointer;
}
.seek::-moz-range-thumb {
border-radius: 50px;
width: 15px;
height: 15px;
background: var(--green-color);
cursor: pointer;
}
.time {
font-size: 12px;
opacity: 0.8;
white-space: nowrap;
}
@media (max-width: 800px) {
.player {
flex-direction: column;
}
.cover {
width: 100%;
height: 180px;
}
.info {
width: auto;
}
.meta {
grid-template-columns: 1fr;
}
.controls {
flex-wrap: wrap;
}
.time {
width: 100%;
}
}
</style>
<div class="player">
<img class="cover" src="${cover}" alt="${song} cover art">
<div class="info">
<div class="meta">
<div class="leftmeta">
<h3>${song}</h3>
<p>${artist}</p>
</div>
<div class="rightmeta">
<div class="credit">
Original Artist: ${originalArtist}
</div>
<div class="credit">
Original Source: ${originalSource}
</div>
</div>
</div>
<audio class="audio">
<source src="${src}" type="${mime}">
</audio>
<div class="controls">
<button class="playBtn"><i class="fa-solid fa-play"></i></button>
<input
class="seek"
type="range"
value="0"
min="0"
max="100">
<span class="time">0:00 / 0:00</span>
</div>
</div>
</div>
`;
// component-local elements
const audio = this.querySelector(".audio");
const playBtn = this.querySelector(".playBtn");
const seek = this.querySelector(".seek");
const time = this.querySelector(".time");
// play / pause
playBtn.addEventListener("click", () => {
if (audio.paused) {
audio.play();
playBtn.innerHTML = '⏸';
} else {
audio.pause();
playBtn.innerHTML = '▶';
}
});
// update seek bar + time
audio.addEventListener("timeupdate", () => {
seek.value =
(audio.currentTime / audio.duration) * 100 || 0;
time.textContent =
formatTime(audio.currentTime)
+ " / " +
formatTime(audio.duration);
});
// seeking
seek.addEventListener("input", () => {
audio.currentTime =
(seek.value / 100) * audio.duration;
});
// reset button when song ends
audio.addEventListener("ended", () => {
playBtn.innerHTML = '▶';
});
// format time helper
function formatTime(sec) {
if (isNaN(sec)) return "0:00";
const m = Math.floor(sec / 60);
const s = Math.floor(sec % 60)
.toString()
.padStart(2, "0");
return `${m}:${s}`;
}
}
}
customElements.define("audio-player", AudioPlayer);
}