抖音下载脚本V0.4
// ==UserScript==
// @name 抖音下载脚本V0.4
// @namespace http://tampermonkey.net/
// @version 0.4
// @description try to take over the world!
// @author LHD
// @match https://www.douyin.com/user/*
// @icon https://www.google.com/s2/favicons?domain=douyin.com
// @grant unsafeWindow
// @grant GM_setClipboard
// ==/UserScript==
let saveurl={}
var current=new Date()
let fullyear=current.getFullYear()
let currentmonth=current.getMonth()
let currentday=current.getDate()
function ControlShowCheckAndNew(target){
if(target.tagName=="svg"){
return true;
}
if(target.className.indexOf('injectvideo')!=-1){
return true;
}
if(target.className.indexOf('control-pos')!=-1){
return true;
}
const prop = Object.keys(target).find(p => p.startsWith('__reactProps'));
if(prop===undefined){
return;
}
let info=target[prop].children.props.awemeInfo
if(info===undefined){
console.log('test')
}
let createTime=info.createTime*1000
let videourl=info.video.playApi
videourl='https://'+videourl.replace('https://','').replace('http://','').replace('//','')
target.classList.add('injectvideo')
var select=document.createElement('label')
select.className='container control-pos'
select.innerHTML=` <input type="checkbox"><div class="checkmark"></div>`
target.append(select)
select.onclick=()=>{
console.log('选中变化了',select.children[0].checked)
if(select.children[0].checked){
//选中
saveurl[videourl]=true;
}else{
//未选中
if(saveurl[videourl]){
delete saveurl[videourl]
}
}
}
var getdate=new Date(createTime)
if(fullyear===getdate.getFullYear()){
if(currentmonth===getdate.getMonth()){
if(currentday===getdate.getDate()){
console.log('选中新的')
let newbutton=document.createElement('button')
newbutton.innerText='NEW'
newbutton.classList.add('newbutton')
target.append(newbutton)
}
}
}
}
const targetNode = document.querySelector('.FeJSrpNN ul')
// 观察器的配置(需要观察什么变动)
const config = {
childList: true, // 观察目标子节点的变化,添加或删除
attributes: true, // 观察属性变动
subtree: true, //默认是false,设置为true后可观察后代节点
};
// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {
// Use traditional 'for loops' for IE 11
console.log('mutationsList',mutationsList)
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((item)=>{
ControlShowCheckAndNew(item)
})
}
}
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);
// 以上述配置开始观察目标节点
debugger;
observer.observe(targetNode, config);
unsafeWindow.onload=()=>{
let list=document.querySelectorAll('.FeJSrpNN ul li')
//处理循环
list.forEach((item)=>{
ControlShowCheckAndNew(item)
})
}
function InsertCopyVideo(){
if(document.querySelector('.copyvideo')!==null){
return;
}
debugger;
let parenttagert=document.querySelector('.J4nwkLQN')
let div=document.createElement("div");
div.innerHTML=`<div class="B10aL8VQ s6mStVxD vMQD6aai gK58qq7e copyvideo"><span style="cursor: pointer;">复制视频</span></div>`
div.onclick=function(event){
let size=Object.keys(saveurl)
let text=size.join('\n')
GM_setClipboard(text)
alert('已设置到剪辑版共'+size.length+"个")
};
parenttagert.append(div);
}
InsertCopyVideo()
setInterval(()=>{
InsertCopyVideo()
}
,1000)
let jumprun=false;
function JumpToBottom(){
if(jumprun==true){
return;
}
jumprun=true;
let timer=setInterval(()=>{
debugger;
let bottomdiv=document.querySelector('.mwbaK9mv .Bllv0dx6')
if(bottomdiv!==null){
if(bottomdiv.innerText==='暂时没有更多了'){
unsafeWindow.scrollTo(0,0)
jumprun=false;
clearInterval(timer)
return;
}
}
unsafeWindow.scrollTo(0,document.body.scrollHeight)
},300)
}
function SelectAllVideo(){
let alltarget=document.querySelectorAll('.control-pos input')
let successnum=Object.keys(saveurl)
let setstatus=false
if(successnum.length===alltarget.length)
{
//取消全部
setstatus=false
}else{
//选择全部
setstatus=true;
}
alltarget.forEach((item)=>{
item.checked=setstatus;
item.parentElement.onclick()
})
}
unsafeWindow.addEventListener('keydown', (evt)=>{
if(evt.ctrlKey){
if(evt.keyCode==40){
//开始设置滚轴
JumpToBottom()
}
if(evt.keyCode==90){
//选择或取消全部视频
SelectAllVideo()
}
}
});
let cssstyle = document.createElement("style");
cssstyle.innerHTML =(`
.injectvideo{
position: relative;
}
.control-pos{
bottom: 20.5px;
right: 12.1px;
position: absolute;
}
.container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.container {
display: block;
cursor: pointer;
font-size: 20px;
user-select: none;
}
/* Create a custom checkbox */
.checkmark {
position: relative;
top: 0;
left: 0;
height: 1.3em;
width: 1.3em;
background-color: #ccc;
border-radius: 25px;
transition: 0.15s;
}
/* When the checkbox is checked, add a blue background */
.container input:checked ~ .checkmark {
background-color: #ff4242;
border-radius: 25px;
transition: 0.15s;
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.container .checkmark:after {
left: 0.45em;
top: 0.25em;
width: 0.25em;
height: 0.5em;
border: solid white;
border-width: 0 0.15em 0.15em 0;
transform: rotate(45deg);
}
.newbutton,
.newbutton::after {
padding: 5px 4px;
font-size: 18px;
background: linear-gradient(45deg, transparent 5%, #ff013c 5%);
border: 0;
color: #fff;
letter-spacing: 3px;
line-height: 1;
box-shadow: 6px 0px 0px #00e6f6;
outline: transparent;
position: relative;
}
.newbutton::after {
--slice-0: inset(50% 50% 50% 50%);
--slice-1: inset(80% -6px 0 0);
--slice-2: inset(50% -6px 30% 0);
--slice-3: inset(10% -6px 85% 0);
--slice-4: inset(40% -6px 43% 0);
--slice-5: inset(80% -6px 5% 0);
content: "HOVER ME";
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, transparent 3%, #00e6f6 3%, #00e6f6 5%, #ff013c 5%);
text-shadow: -3px -3px 0px #f8f005, 3px 3px 0px #00e6f6;
clip-path: var(--slice-0);
}
.newbutton:hover::after {
animation: 1s glitch;
animation-timing-function: steps(2, end);
}
.newbutton{
position: absolute;
left: 15.5px;
top: 0;
}
`);
document.body.appendChild(cssstyle);