matab-panel/public/js/audio-speed.js

93 lines
2.8 KiB
JavaScript

(function () {
var SPEEDS = [1, 1.25, 1.5, 2, 0.5, 0.75];
function injectStyles() {
if (document.getElementById('fp-speed-styles')) return;
var s = document.createElement('style');
s.id = 'fp-speed-styles';
s.textContent = `
.fp-speed-toggle {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 36px;
z-index: 30;
padding: 2px 7px;
border-radius: 4px;
font-size: 11px;
font-family: monospace;
font-weight: 700;
border: none;
cursor: pointer;
background: rgba(59,130,246,.9);
color: #fff;
line-height: 1.5;
transition: background .15s, transform .1s;
user-select: none;
}
.fp-speed-toggle:hover {
background: rgba(37,99,235,1);
}
.fp-speed-toggle:active {
transform: translateY(-50%) scale(.92);
}
/* Force overflow visible on filepond file element */
.filepond--file {
overflow: visible !important;
}
`;
document.head.appendChild(s);
}
function getNextSpeed(current) {
var idx = SPEEDS.indexOf(current);
return SPEEDS[(idx + 1) % SPEEDS.length];
}
function processItem(item) {
var audio = item.querySelector('audio');
if (!audio) return;
if (item.querySelector('.fp-speed-toggle')) return;
var fileEl = item.querySelector('.filepond--file');
if (!fileEl) return;
var btn = document.createElement('button');
btn.type = 'button';
btn.className = 'fp-speed-toggle';
btn.textContent = '1x';
btn.dataset.fpSpeed = '1';
btn.addEventListener('click', function (e) {
e.stopPropagation();
e.preventDefault();
var cur = parseFloat(btn.dataset.fpSpeed);
var next = getNextSpeed(cur);
btn.dataset.fpSpeed = next;
btn.textContent = next + 'x';
audio.playbackRate = next;
audio.defaultPlaybackRate = next;
});
fileEl.appendChild(btn);
}
function scan() {
document.querySelectorAll('.filepond--item').forEach(processItem);
}
function cleanOld() {
document.querySelectorAll('.fp-speed-bar').forEach(function (el) { el.remove(); });
}
injectStyles();
cleanOld();
var observer = new MutationObserver(function () {
cleanOld();
scan();
});
observer.observe(document.body, { childList: true, subtree: true });
scan();
})();