内容目录
背景
小宇宙博客网页不能登陆,没有记录,我很久之前想写一个脚本解决问题
用途
网页播放博客的时候,关闭网页再次打会,点击播放会从上次播放地方继续
过程
- 通过美团tabbit AI直接生成脚本
- 修复几次发现有问题,懒的跟AI交换
- 分析代码,我知道大概逻辑,因为以前不了解H5 播放器的操作知识点
- 重新手写一份
脚本
(function () {
console.log("脚本加载中")
function OnceRun() {
if (!window.__podcastProgressRecorder) {
window.__podcastProgressRecorder = true
return true
} else {
return false
}
}
if (!OnceRun()) {
console.warn("脚本不需要重复加载")
return;
}
//定义属性
var save_timer;
var RECORD_PRIFX = "_YU_RECORD_PROCESS_"
var is_need_restore = true
var target_time //目标播放的时间
let save_interval //保存的定时器
var URL_KEY = "episode"
console.log("===============页面加载了=================")
//第一次加载,初始化
async function initSub() {
if (window.location.pathname.indexOf(URL_KEY) > 0) {
let audio = await waitAudio();
if (audio == null) {
console.log("声音元素没有找到")
return
} else {
console.log("声音元素")
console.info(audio)
}
bindAutioEvent(audio);
} else {
console.log("当前url,不进行恢复和保存")
}
}
function init() {
console.log("进行初始化")
console.log(document.readyState)
if (document.readyState == "loading") {
window.addEventListener("DOMContentLoaded", initSub)
} else {
initSub()
}
}
//等待声音audio
async function waitAudio(maxRetries = 100) {
console.log("正在查找声音元素")
return new Promise((resolve) => {
let retries = 0;
const interval = setInterval(() => {
const audio = document.querySelector('audio');
if (audio) {
clearInterval(interval);
resolve(audio);
}
retries++;
if (retries >= maxRetries) {
clearInterval(interval);
resolve(null);
}
}, 200);
});
}
//获取记录
function getStoreageRecord() {
let key = RECORD_PRIFX + window.location.pathname
return localStorage.getItem(key)
}
//保存记录
function saveRecord(time) {
let key = RECORD_PRIFX + window.location.pathname
if (window.location.pathname.indexOf("episode") >= 0) {
console.log("save:" + key + " value:" + time)
localStorage.setItem(key, time)
} else {
console.log("当前url,不保存进度")
}
}
/**
*
* @param audio {HTMLAudioElement}
*/
function checkRestoreRecord(audio) {
let r = getStoreageRecord()
console.log("存放的值")
console.info(r)
if (r != undefined && r != null) {
console.log("进行恢复设置")
target_time = r
}
}
/**
*
* @param audio {HTMLAudioElement}
*/
function autoRestoreRecord(audio) {
console.log("进入 autoRestoreRecord")
if (is_need_restore) {
if (target_time) {
let v = target_time - audio.currentTime
if (v > 0 && v >= 5) {
console.log("正在恢复中")
console.log("-----------------:" + target_time + " current_time:" + audio.currentTime)
audio.currentTime = target_time
} else {
console.log("恢复成功")
target_time = false
is_need_restore = false
}
}
}
}
/**
*
* @param audio {HTMLAudioElement} audio - HTML5 Audio 元素
*/
function bindAutioEvent(audio) {
if (!audio) return
console.log("进行绑定声音元素")
audio.addEventListener("play", () => {
console.log("声音进行播放了")
console.info(formatTime(audio.currentTime))
})
audio.addEventListener("pause", () => {
console.log("暂停播放")
console.info(formatTime(audio.currentTime))
})
audio.addEventListener("loadedmetadata", () => {
console.log("loadedmetadata")
})
audio.addEventListener("playing", () => {
console.log("播放中====>")
autoRestoreRecord(audio)
})
audio.addEventListener("canplay", () => {
console.log("canplay")
})
audio.addEventListener("seeked", () => {
console.log("seeked")
})
if (is_need_restore) {
checkRestoreRecord(audio)
}
createSaveInterval(audio)
}
// 格式化时间
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs.toString().padStart(2, '0')}`;
}
function createSaveInterval(audio) {
if (save_interval) {
clearInterval(save_interval)
save_interval = false
}
save_interval = setInterval(() => {
console.log("进入定时的器")
if (audio) {
console.log("is_need_resotre:" + is_need_restore + " target_time:" + target_time)
if (is_need_restore == false || (is_need_restore == true && !target_time)) {
if (!audio.paused && !audio.ended && audio.currentTime > 0) {
saveRecord(audio.currentTime)
}
}
}else{
console.log("audio 无效")
}
}, 1000);
}
//网页变化
function onWebChange() {
console.log("========网页进行变化了,进行重新初始化=======")
is_need_restore = true; //重新初始化
initSub()
}
init();
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
history.pushState = function (...args) {
console.log("push state ===>")
originalPushState.apply(history, args);
onWebChange();
};
history.replaceState = function (...args) {
console.log("replaceState ===>")
originalReplaceState.apply(history, args);
onWebChange();
};
})();
设置
- 打开我的妙招
- 点击右上角创建脚本
- 粘贴代码
- 设置自动运行和指定网址
指定网址:https://www.xiaoyuzhoufm.com/episode
这样子只有小宇宙博客界面详情才会触发,同时一定要打开每次自动运行,不然必须手动触发
总结
- AI 会减低创建脚本难度
- 复杂度增加AI 交流成本也会变更高,其实我不认为AI 编程是未来,虽然很多说AI 编程是未来,现在手写代码是古法编程,我反而觉得AI 编程 对于demo 或者小项目可以,对于很多项目是不合适,我反而觉得是邪修,一句话 这个世界没有银弹来解决一些事务
