Alist 增加视频跳转链接页面自动定位到指定时间播放的功能
功能介绍:
- 在 Alist 页面复制播放的视频链接到剪切板,链接中自动附上当前已播放的时间
- 把链接粘贴到思源笔记中
- 点击刚才粘贴的视频链接,自动跳转到 Alist 页面并自动定位到刚才已播放的时间点
效果:
代码如下(把以下代码放到 alist 管理页面,设置-》全局-》自定义内容里即可)
<script>
(function() {
// 监听哪些视频格式
const videos = ['.mp4','.avi', '.webm', '.ogg'];
// 监听哪些音频格式
const audios = ['.mp3', '.wav', '.m4a'];
// 监听视频格式
observeElementExist('a[href^="iina://"]', a => {
if(!videos.some(extension => location.pathname.endsWith(extension))){
return;
}
const shareBtn = document.createElement('button');
shareBtn.textContent = "复制";
shareBtn.style.padding = '0px 15px';
shareBtn.style.cursor = 'pointer';
shareBtn.onclick = () => {
const title = document.querySelector('nav ol li:last-child').textContent;
const video = document.querySelector('video');
const time = video.currentTime;
const text = `[${title} [${convertSecondsToMinutesAndSeconds(time)}]](${genUrlParameter(location.href, 'time', time)})`;
copyToClipboard(text);
shareBtn.textContent = "已复制";
setTimeout(() => { shareBtn.textContent = "复制"; }, 1500);
};
// 将shareBtn插入到目标a元素之前
a.parentElement.insertBefore(shareBtn, a);
//获取URL参数并调整到对应的时间
const time = parseFloat(getUrlParameter(location.href, 'time'));
if(time){
// 去掉上次播放提示
const lastPlayTips = document.querySelector('.art-layer.art-layer-auto-playback');
if(lastPlayTips){
let count = 0;
const timer = setInterval(()=>{
count++;
if(count>50) clearInterval(timer);
if(lastPlayTips.style.display === 'flex') {
lastPlayTips.style.display = 'none';
clearInterval(timer);
}
}, 100);
}
// 视频跳转时间
const video = document.querySelector('video');
video.currentTime = time;
}
});
//监听音频格式化(不支持获取当前时间,因为无法获取aplayer播放器实例)
observeElementExist('.aplayer-music', el => {
if(el.dataset.loaded === 'true') return;
el.dataset.loaded = true;
if(!audios.some(extension => location.pathname.endsWith(extension))){
return;
}
el.style.overflow = 'visible';
const shareBtn = document.createElement('button');
shareBtn.textContent = "复制";
shareBtn.style.padding = '0px 5px';
shareBtn.style.cursor = 'pointer';
shareBtn.style.float = 'right';
shareBtn.onclick = () => {
const title = el.querySelector('.aplayer-title').textContent;
const text = `[${title}](${location.href})`;
copyToClipboard(text);
shareBtn.textContent = "已复制";
setTimeout(() => { shareBtn.textContent = "复制"; }, 1500);
};
el.appendChild(shareBtn);
});
function getUrlParameter(url, param) {
const urlParams = new URLSearchParams(new URL(url).search);
return urlParams.get(param);
}
function genUrlParameter(url, param, value) {
const urlParams = new URLSearchParams(new URL(url).search);
urlParams.set(param, value);
const newUrl = url.split('?')[0] + '?' + urlParams.toString();
return newUrl;
}
function convertSecondsToMinutesAndSeconds(seconds) {
let minutes = Math.floor(seconds / 60);
const secondsRemaining = Math.floor(seconds % 60);
// 格式化分秒数
const formattedSeconds = secondsRemaining.toString().padStart(2, '0');
minutes = minutes.toString().padStart(2, '0');
return `${minutes}:${formattedSeconds}`;
}
function copyToClipboard(contents) {
if ('clipboard' in navigator) {
navigator.clipboard.writeText(contents);
return;
}
const textarea = document.createElement('textarea');
textarea.value = contents;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
function observeElementExist(selector, callback) {
const handleMutations = (mutationsList, observer) => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches(selector)) {
callback(node);
} else if (node && node.querySelector && node.querySelector(selector)) {
callback(node.querySelector(selector));
}
});
}
}
};
// 创建一个MutationObserver实例
const config = { attributes: false, childList: true, subtree: true };
const observer = new MutationObserver(handleMutations);
// 选择需要监听的父节点
const targetNode = document.body; // 或者选择其他合适的父节点
// 开始监听目标节点的变化
observer.observe(targetNode, config);
}
})();
</script>
关联 https://github.com/loonghfut/siyuan-alist/issues/2#issuecomment-2428711820
