是否有 javascript 删除 Youtube 播放列表中的重复视频?
Is there a javascript to remove duplicate videos in a Youtube playlist?
自从 YouTube discontinued 界面上的 remove duplicates
按钮(大约在同一时间他们停止使用非聚合界面)以来,用户无法删除他们的播放列表。我到处寻找工具来做到这一点,但无济于事。我发现这个脚本可以从播放列表中删除所有视频,想知道是否可以修改它(由比我更了解 javascript 的人修改)以仅删除重复的视频:
setInterval(function () {
document.querySelector('#primary button[aria-label="Action menu"]').click();
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (var i = 0; i < things.snapshotLength; i++) {
things.snapshotItem(i).click();
}
}, 1000);
实际上(截至 2021-11-07)仍然有一种官方方法可以创建播放列表的新的无重复副本:
打开 Youtube Music 并创建播放列表 https://music.youtube.com/library/playlists
(播放列表需要在youtube music上创建,否则播放列表将在youtube music上不可见...)
在常规 youtube 上打开您要从中删除重复项的播放列表,例如:https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb
使用第一个视频的菜单(视频右侧的三个点)并选择“保存到播放列表”并将播放列表的第一个视频保存到新创建的 youtube 音乐播放列表(这是在步骤 1 中创建的)
将 url 中的 www
替换为 music
以访问旧播放列表的 YouTube 音乐视图,例如:https://music.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb
使用菜单(三个点)和select“添加到播放列表”
将您的旧播放列表添加到新的(在步骤 1 中创建的)播放列表。由于新播放列表已经包含旧播放列表的视频(在第 3 步中添加),如果您想跳过重复项,您现在会收到一个问题,所以...
...你select“跳过重复项”。这似乎不仅会跳过最初已包含在您的新播放列表中的视频,而且还会只添加旧播放列表中的每个视频一次,从而删除重复项。
备选方案:Javascript解决方案:
这不是很好,因为它似乎只能在每次按下按钮后进入睡眠状态,但这对我有用:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function removeduplicates() {
let titles = document.querySelectorAll('#primary #video-title')
let href_pattern = RegExp('https?://www\.youtube\.com/watch\?v=[^&]*&list=[^&]*&index=')
titles = Array.from(titles).filter(t => href_pattern.test(t.href))
let lastid='';
for (let i = 0; i < titles.length; i++) {
let id = titles[i].href.match(/\?v=([^&]+)/)[1]
if(id == lastid){
titles[i].focus()
titles[i].parentElement.parentElement.parentElement.parentElement.parentElement.querySelector('button[aria-label="Action menu"]').click()
await sleep(100)
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
await sleep(300)
for (var j = 0; j < things.snapshotLength; j++) {
things.snapshotItem(j).click();
}
console.log(titles[i].innerText)
}
lastid=id;
}
}
removeduplicates()
另请注意,它仅在您的语言设置为英语时才有效,因为删除按钮是通过字符串“Remove from”找到的。
要运行这个,您需要在播放列表的播放列表页面(例如https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb),您要从中删除重复项。然后按 F12,将代码粘贴到 javascript 控制台并按回车键。
注意:仅当两个相同的视频紧随其后时,才会删除重复项,因此您需要按例如播放列表排序。视频发布日期。
注意2:只考虑当前加载到浏览器中的视频window,因此您需要向下滚动到播放列表的末尾,这样才能真正加载所有视频。
我实际上使用了脚本并对其进行了一些改进。这个新脚本根本不需要对播放列表进行排序
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function $$(selector,context=document.documentElement){return[...context?.querySelectorAll?.(selector) ?? []]}
async function removeduplicates() {
let titles = $$("#primary a#video-title")
.filter((i,j,k)=>k.
findIndex(k=>k.href.includes(Object.fromEntries(new URLSearchParams(i.href))['https://www.youtube.com/watch?v']))!==j)
for (let i = 0; i < titles.length; i++) {
titles[i].focus()
titles[i].closest("#contents > *").querySelector('button[aria-label="Action menu"]').click()
await sleep(100)
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
await sleep(300)
for (var j = 0; j < things.snapshotLength; j++) {
things.snapshotItem(j).click();
}
console.log(titles[i].innerText)
}
}
removeduplicates()
它不检查视频标题,而是检查 hrefs 是否有重复项,仅隔离重复的视频,然后删除重复项。亲自测试过,效果很好
自从 YouTube discontinued 界面上的 remove duplicates
按钮(大约在同一时间他们停止使用非聚合界面)以来,用户无法删除他们的播放列表。我到处寻找工具来做到这一点,但无济于事。我发现这个脚本可以从播放列表中删除所有视频,想知道是否可以修改它(由比我更了解 javascript 的人修改)以仅删除重复的视频:
setInterval(function () {
document.querySelector('#primary button[aria-label="Action menu"]').click();
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (var i = 0; i < things.snapshotLength; i++) {
things.snapshotItem(i).click();
}
}, 1000);
实际上(截至 2021-11-07)仍然有一种官方方法可以创建播放列表的新的无重复副本:
打开 Youtube Music 并创建播放列表 https://music.youtube.com/library/playlists (播放列表需要在youtube music上创建,否则播放列表将在youtube music上不可见...)
在常规 youtube 上打开您要从中删除重复项的播放列表,例如:https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb
使用第一个视频的菜单(视频右侧的三个点)并选择“保存到播放列表”并将播放列表的第一个视频保存到新创建的 youtube 音乐播放列表(这是在步骤 1 中创建的)
将 url 中的
www
替换为music
以访问旧播放列表的 YouTube 音乐视图,例如:https://music.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb使用菜单(三个点)和select“添加到播放列表” 将您的旧播放列表添加到新的(在步骤 1 中创建的)播放列表。由于新播放列表已经包含旧播放列表的视频(在第 3 步中添加),如果您想跳过重复项,您现在会收到一个问题,所以...
...你select“跳过重复项”。这似乎不仅会跳过最初已包含在您的新播放列表中的视频,而且还会只添加旧播放列表中的每个视频一次,从而删除重复项。
备选方案:Javascript解决方案:
这不是很好,因为它似乎只能在每次按下按钮后进入睡眠状态,但这对我有用:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function removeduplicates() {
let titles = document.querySelectorAll('#primary #video-title')
let href_pattern = RegExp('https?://www\.youtube\.com/watch\?v=[^&]*&list=[^&]*&index=')
titles = Array.from(titles).filter(t => href_pattern.test(t.href))
let lastid='';
for (let i = 0; i < titles.length; i++) {
let id = titles[i].href.match(/\?v=([^&]+)/)[1]
if(id == lastid){
titles[i].focus()
titles[i].parentElement.parentElement.parentElement.parentElement.parentElement.querySelector('button[aria-label="Action menu"]').click()
await sleep(100)
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
await sleep(300)
for (var j = 0; j < things.snapshotLength; j++) {
things.snapshotItem(j).click();
}
console.log(titles[i].innerText)
}
lastid=id;
}
}
removeduplicates()
另请注意,它仅在您的语言设置为英语时才有效,因为删除按钮是通过字符串“Remove from”找到的。
要运行这个,您需要在播放列表的播放列表页面(例如https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb),您要从中删除重复项。然后按 F12,将代码粘贴到 javascript 控制台并按回车键。
注意:仅当两个相同的视频紧随其后时,才会删除重复项,因此您需要按例如播放列表排序。视频发布日期。
注意2:只考虑当前加载到浏览器中的视频window,因此您需要向下滚动到播放列表的末尾,这样才能真正加载所有视频。
我实际上使用了脚本并对其进行了一些改进。这个新脚本根本不需要对播放列表进行排序
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function $$(selector,context=document.documentElement){return[...context?.querySelectorAll?.(selector) ?? []]}
async function removeduplicates() {
let titles = $$("#primary a#video-title")
.filter((i,j,k)=>k.
findIndex(k=>k.href.includes(Object.fromEntries(new URLSearchParams(i.href))['https://www.youtube.com/watch?v']))!==j)
for (let i = 0; i < titles.length; i++) {
titles[i].focus()
titles[i].closest("#contents > *").querySelector('button[aria-label="Action menu"]').click()
await sleep(100)
var things = document.evaluate(
'//span[contains(text(),"Remove from")]',
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
await sleep(300)
for (var j = 0; j < things.snapshotLength; j++) {
things.snapshotItem(j).click();
}
console.log(titles[i].innerText)
}
}
removeduplicates()
它不检查视频标题,而是检查 hrefs 是否有重复项,仅隔离重复的视频,然后删除重复项。亲自测试过,效果很好