// ==UserScript== // @name m3u8-downloader // @namespace https://github.com/Momo707577045/m3u8-downloader // @version 0.10.1 // @description https://github.com/Momo707577045/m3u8-downloader 配套插件 // @author Momo707577045 // @include * // @exclude http://blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html // @exclude https://blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html // @exclude https://www.bilibili.com/* // @downloadURL https://blog.luckly-mjw.cn/tool-show/m3u8-downloader/m3u8-downloader.user.js // @updateURL https://blog.luckly-mjw.cn/tool-show/m3u8-downloader/m3u8-downloader.user.js // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; var showMp4 = true var m3u8Target = '' var mp4Objs = [] var originXHR = window.XMLHttpRequest var windowOpen = window.open function ajax(options) { options = options || {}; let xhr = new originXHR(); if (options.type === 'file') { xhr.responseType = 'arraybuffer'; } xhr.onreadystatechange = function () { if (xhr.readyState === 4) { let status = xhr.status; if (status >= 200 && status < 300) { options.success && options.success(xhr.response); } else { options.fail && options.fail(status); } } }; xhr.open("GET", options.url, true); xhr.send(null); } // 普通下载 function downloadWithA(url, name) { const a = document.createElement('a') a.href = url a.download = name a.style.display = 'none' document.body.appendChild(a) a.click() a.remove() } // 检测 m3u8 链接的有效性 function checkM3u8Url(url) { ajax({ url, success: (fileStr) => { if (/(png|image|ts|jpg|mp4|jpeg|EXTINF)/.test(fileStr)) { appendDom() document.getElementById('m3u8-jump').style.display = 'block' document.getElementById('m3u8-close').style.display = 'block' document.getElementById('m3u8-append').style.display = 'block' const urlObj = new URL(url) urlObj.searchParams.append('title', getTitle()) m3u8Target = urlObj.href console.log('【m3u8】----------------------------------------') console.log(urlObj) console.log('http://blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html?source=' + m3u8Target) } } }) } // 定时器,检查 mp4 视频资源 function checkVideo() { let $videoList = document.getElementsByTagName('video') for (let i = 0, length = $videoList.length; i < length; i++) { const url = $videoList[i].currentSrc if (url.indexOf('.mp4') > 0 && !mp4Objs.find(mp4 => mp4.url === url)) { appendDom(); document.getElementById('mp4-show').style.display = 'block' mp4Objs.push({ url, fileName: url.slice(url.lastIndexOf('/') + 1).split('?')[0], }); } } setTimeout(checkVideo, 3000); } function resetAjax() { if (window._hadResetAjax) { // 如果已经重置过,则不再进入。解决开发时局部刷新导致重新加载问题 return } window._hadResetAjax = true var originOpen = originXHR.prototype.open window.XMLHttpRequest = function () { var realXHR = new originXHR() realXHR.open = function (method, url) { url.toString() && url.toString().indexOf('.m3u8') > 0 && checkM3u8Url(url.toString()) // if (url.toString() && url.toString().toLocaleLowerCase().indexOf('.mp4') > 0) { // appendDom(); // document.getElementById('mp4-show').style.display = 'block' // mp4Objs.push({ // url, // fileName: url.slice(url.lastIndexOf('/') + 1).split('?')[0], // }); // } originOpen.call(realXHR, method, url) } return realXHR } window.XMLHttpRequest.UNSENT = originXHR.UNSENT; window.XMLHttpRequest.OPENED = originXHR.OPENED; window.XMLHttpRequest.HEADERS_RECEIVED = originXHR.HEADERS_RECEIVED; window.XMLHttpRequest.LOADING = originXHR.LOADING; window.XMLHttpRequest.DONE = originXHR.DONE; window.XMLHttpRequest.prototype = originXHR.prototype; } // 获取顶部 window title,因可能存在跨域问题,故使用 try catch 进行保护 function getTitle() { let title = document.title; try { title = window.top.document.title } catch (error) { console.log(error) } return title } function appendDom() { if (document.getElementById('m3u8-download-dom')) { return } var domStr = `
MP4下载
跳转下载
注入下载
` var $section = document.createElement('section') $section.id = 'm3u8-download-dom' $section.style.position = 'fixed' $section.style.zIndex = '9999' $section.style.bottom = '20px' $section.style.right = '20px' $section.style.textAlign = 'center' $section.innerHTML = domStr document.body.appendChild($section); var mp4Show = document.getElementById('mp4-show') var m3u8Jump = document.getElementById('m3u8-jump') var m3u8Close = document.getElementById('m3u8-close') var m3u8Append = document.getElementById('m3u8-append') mp4Show.addEventListener('click', function () { showMp4 = !showMp4 mp4Show.innerHTML = showMp4 ? 'MP4下载' : '关闭MP4' switchMp4Download(); }) m3u8Close.addEventListener('click', function () { $section.remove() }) m3u8Jump.addEventListener('click', function () { windowOpen('//blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html?source=' + m3u8Target) }) m3u8Append.addEventListener('click', function () { var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?1f12b0865d866ae1b93514870d93ce89"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); ajax({ url: 'https://blog.luckly-mjw.cn/tool-show/m3u8-downloader/index.html?t=' + new Date().getTime(), success: (fileStr) => { let fileList = fileStr.split(`