// ==UserScript== // @name 抖音获取视频0.5 // @namespace https://bbs.tampermonkey.net.cn/ // @version 0.5.0 // @description try to take over the world! // @author You // @match https://www.douyin.com/user/* // @grant unsafeWindow // @grant GM_setClipboard // ==/UserScript== let videoData = new Map() function handleVideoItem(item) { if (item.className.indexOf('injectvideo') != -1) { return; } item.classList.add('injectvideo') const selectDom = document.createElement('label') selectDom.className = 'container control-pos' selectDom.innerHTML = `
` selectDom.addEventListener('click', function (event) { if (selectDom.children[0].checked) { const prop = Object.keys(item).find(p => p.startsWith('__reactProps')); if (prop === undefined) { return; } let info = item[prop].children[0].props.info let videourl = info.video.playApi videourl = 'https://' + videourl.replace('https://', '').replace('http://', '').replace('//', '') console.log('videourl', videourl) videoData.set(selectDom, videourl) } else { videoData.delete(selectDom) } },) item.append(selectDom) } function enableObserve() { const domSelector = '.UFuuTZ1P ul' document.querySelectorAll(domSelector + ' li').forEach((item) => { handleVideoItem(item) }) const targetNode = document.querySelector(domSelector) const config = { childList: true, }; const callback = function (mutationsList, observer) { for (let mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach((item) => { handleVideoItem(item) }) } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); } function renderView() { const renderDownloadBtn = () => { if (document.querySelector('.copyvideo') !== null) { return true; } let div = document.createElement("div"); div.innerHTML = `
复制视频
` div.onclick = function (event) { let text = '' for (var videoURL of videoData.values()) { text += videoURL + '\n' } GM_setClipboard(text) alert('已设置到剪辑版共' + videoData.size + "个") }; document.body.append(div); } renderDownloadBtn() //防dom覆盖 // setInterval(() => { // renderDownloadBtn() // }, 1000) } unsafeWindow.onload = () => { enableObserve() renderView() } let jumpRun=false; function jumpToBottom(){ if(jumpRun==true){ return; } jumpRun=true; let timer=setInterval(()=>{ let bottomdiv=document.querySelector('.kwodhZJl .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 videoCheckList=document.querySelectorAll('.control-pos input') let willStatus=false if(videoData.size===videoCheckList.length) { //取消全部 willStatus=false }else{ //选择全部 willStatus=true; } videoCheckList.forEach((item)=>{ item.checked=willStatus; item.parentElement.dispatchEvent(new Event('click')) }) } unsafeWindow.addEventListener('keydown', (evt) => { if (evt.ctrlKey) { if (evt.keyCode == 40) { //开始设置滚轴 jumpToBottom() } if (evt.keyCode == 90) { //选择或取消全部视频 selectAllVideo() } } }); let cssstyle = document.createElement("style"); cssstyle.innerHTML = (` .copyvideo{ position: fixed; right: 0; top: 182px; z-index: 99; } .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: 14px; left: 7px; height: 1.3em; z-index: 99; cursor: pointer; width: 1.3em; background-color: #ccc; border-radius: 25px; } /* 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);