// ==UserScript== // @name Nico dl // @namespace http://tampermonkey.net/ // @version 0.2 // @description 下载N站视频 | Download video from nicovideo.jp // @author ctrn43062 // @include *//www.nicovideo.jp/watch/sm* // @icon https://www.google.com/s2/favicons?domain=nicovideo.jp // @grant none // @note 2022-2-10 添加下载视频高清封面功能 // @license MIT // @downloadURL none // ==/UserScript== const IS_HLS_DISABLED = 'DMCSource.isHLSDisabled'; const DOWNLOAD_SVG = `` const COVER_SVG = `` function createButton(svg, title, disabled = false) { const button = document.createElement('button'); button.className = 'ActionButton ControllerButton PlayerRepeatOnButton'; button.innerHTML = svg; button.setAttribute('data-title', title); disabled && button.setAttribute('disabled', disabled); return button; } function insertButtonToVideoControllBar(button) { const playbackRateButton = document.querySelector('.ActionButton.PlaybackRateButton'); const wrapper = playbackRateButton.parentElement; wrapper.insertBefore(button, playbackRateButton); } function createDownloadVideoButton() { const downloadButton = createButton(DOWNLOAD_SVG, '下载视频', true); insertButtonToVideoControllBar(downloadButton); return { setSrc: function(src) { downloadButton.removeAttribute('disabled'); downloadButton.onclick = function() { window.open(src) }; }, disable: function() { downloadButton.setAttribute('disabled', true); } } } function createDownloadCoverButton() { const button = createButton(COVER_SVG, '下载封面'); insertButtonToVideoControllBar(button); const getCoverURL = () => { let original = ''; document.querySelectorAll('[type="application/ld+json"][data-react-helmet]').forEach(item => { const json = JSON.parse(item.textContent); if (json['@type'] === 'VideoObject') { json['thumbnailUrl'].forEach(thumb => { if (thumb.indexOf('original') !== -1) { original = thumb; } }) } }) return original; } const updateCoverURL = function() { const cover_url = getCoverURL(); button.removeAttribute('disabled'); button.onclick = () => { /* const download = document.createElement('a'); download.setAttribute('download', ''); download.setAttribute('target', '_blank'); download.href = cover_url; download.click(); download.remove(); */ open(cover_url); } } updateCoverURL(); return { updateCoverURL: updateCoverURL, disable: function() { button.setAttribute('disabled', true); } } } (function() { 'use strict'; const isHttp = localStorage.getItem(IS_HLS_DISABLED); if (isHttp === null || isHttp === 'false') { localStorage.setItem(IS_HLS_DISABLED, 'true'); location.reload(); } const downloadCoverButton = createDownloadCoverButton(); const downloadVideoButton = createDownloadVideoButton(); const observer = new MutationObserver(mutationsList => { for (let mutation of mutationsList) { const target = mutation.target; if (mutation.attributeName === 'src') { if (target.src) { downloadVideoButton.setSrc(target.src); downloadCoverButton.updateCoverURL(); } else { downloadVideoButton.disable(); downloadCoverButton.disable(); } } } }); const video = document.querySelector('#MainVideoPlayer > video'); observer.observe(video, { attributes: true }); })();