您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Extract web video title
// ==UserScript== // @name Get Page Title // @description Extract web video title // @namespace https://greasyfork.org/users/3920 // @match http://*/* // @match https://*/* // @version 0.0.1.20251006121143 // ==/UserScript== (function () { let GetJson = function (url, options = {}) { return fetch(url, options) .then((response) => { return response.json(); }) .then((data) => { return data; }); }; copyToClipboard = function(val) { let t = document.createElement("textarea"); document.body.appendChild(t); t.value = val; t.select(); document.execCommand('copy'); document.body.removeChild(t); } function CreateTable(col, row, color = "") { if (color === "") color = "white"; let row_dom = document.createElement('div'); row_dom.setAttribute('id', row); row_dom.setAttribute('style', 'color:' + color + ';font:12px Meiryo;'); row_dom.setAttribute('onclick', 'copyToClipboard(this.getAttribute("value"));'); let col_dom = document.getElementById(col); if(col_dom === null) { col_dom = document.createElement('div'); col_dom.setAttribute('id', col); col_dom.setAttribute('style', 'display:table-cell;padding:0px 10px 0px 10px; vertical-align:middle;'); let table_dom = document.getElementById('resulttable'); if(table_dom === null) CreateLayout(); table_dom = document.getElementById('resulttable'); if(table_dom !== null) table_dom.appendChild(col_dom); } col_dom.appendChild(row_dom); } function CreateLayout(color) { let trends_dom = document.getElementById('extractresult'); if (trends_dom !== null) trends_dom.outerHTML = ""; trends_dom = document.createElement('div'); trends_dom.setAttribute('id', 'extractresult'); let title_dom = document.createElement('strong'); title_dom.innerHTML = [ '<div style="display: block; text-align:center; width: 100%; padding: 0px; margin: auto; vertical-align: middle; border-spacing: 0px"><div id="resulttable" style="display: inline-table;">', '</div></div>' ].join(' '); trends_dom.appendChild(title_dom); trends_dom.style.cssText = [ 'background: rgba(55, 55, 55, 0.5);', 'color: #fff;', 'padding: 0px;', 'position: fixed;', 'z-index:102400;', 'width:100%;', 'font: 12px Meiryo;', 'vertical-align: middle;', ].join(' '); document.body.style.cssText = 'position: relative; margin-top: 0px'; document.body.insertBefore(trends_dom, document.body.firstElementChild); } function SetResult(name, value, col_id, row_id, color = "") { let elem = document.getElementById(row_id); if (elem === null) CreateTable(col_id, row_id, color); elem = document.getElementById(row_id); if (elem !== null) { elem.setAttribute('value', value); elem.innerHTML = name; } } function Convert(title) { return title.replace(/\//g, "/").replace(/!/g, "!").replace(/\?/g, "?").replace(/&/g, "&").replace(/\^/g, "^").replace(/:/g, ":").replace(/%/g, "%").replace(/\</g, "〈").replace(/\>/g, "〉"); } function TverVideo(filename) { if (!window.videojs) return; for (let src of window.videojs.players[Object.keys(window.videojs.players)[0]].mediainfo.sources) { if (/mpegurl/.test(src.type)) { //console.log(src); SetResult(`Video : ${filename}`, `${src.src}\n${filename}\n`, "right", "video"); break; } } } function TverKey() { /** * 주어진 시간만큼 현재 시간에서 더한 값을 밀리초 단위의 타임스탬프로 반환합니다. * @param {object} options - 더할 시간을 나타내는 객체입니다. 예: { hours: 9 } * @returns {number} - 1970-01-01T00:00:00Z부터 경과한 시간을 밀리초로 나타낸 타임스탬프입니다. */ function timeMilliseconds(options = {}) { const { days = 0, hours = 0, minutes = 0, seconds = 0 } = options; const future = new Date(); future.setDate(future.getDate() + days); future.setHours(future.getHours() + hours); future.setMinutes(future.getMinutes() + minutes); future.setSeconds(future.getSeconds() + seconds); return future.getTime(); } const futureTimestamp = timeMilliseconds({ hours: 9 }); const date = new Date(futureTimestamp); // UTC 기준 월을 가져옵니다 (0 = 1월, 1 = 2월, ...). 1을 더해 1-12 범위로 맞춥니다. const month = date.getUTCMonth() + 1; // 파이썬의 'or'와 동일한 기능을 하는 논리 연산자 '||'를 사용합니다. // month % 6의 결과가 0 (falsy)이면 6을 할당합니다. const key_idx = (month % 6) || 6; return key_idx; } async function TverVideoDownload(pid, vid) { let _STREAKS_API_INFO = await GetJson('https://player.tver.jp/player/streaks_info_v2.json'); let info = await GetJson(`https://mocho.pp.ua/tver/info.php?pid=${pid}&vid=${vid}&key=${_STREAKS_API_INFO[pid]['api_key'][`key0${TverKey()}`]}`); if (undefined === info.sources) return ''; for (let src of info.sources) { if ('1920x1080' == src.resolution) return src.src; } return ''; /* a=document.createElement('a'); a.href=`ytdlp:tver@_@${filename}@_@null@_@${window.location.href}`; a.click(); a.remove(); */ } async function TverInfo(json) { let filename = ""; if (json.broadcastDateLabel !== undefined) { let date = /((\d+)[^\d]+(\d+)|(\d{4})).+/gm.exec(json.broadcastDateLabel); if(date !== null) { if(date[4] === undefined) { let today = new Date(); let yyyy = today.getFullYear(); let mm = (date[2].length > 1 ? "" : "0") + date[2]; let dd = (date[3].length > 1 ? "" : "0") + date[3]; filename = yyyy + mm + dd; } else { filename = date[4]; } } } if (json.share !== undefined && json.share.text !== undefined && json.share.text.match(/([^\n]+)/)) { filename += (filename.length === 0 ? "" : " ") + RegExp.$1; } let episode = document.querySelectorAll('span[class^="titles_title"]'); if(json.title !== undefined && json.title !== "") filename += " " + json.title; /* let onair = document.querySelectorAll('div[class^="description_metaDetail"]'); if(onair.length > 0 && onair[0].innerText !== "") { onair = onair[0].getElementsByTagName("span"); if(onair.length > 1 && onair[1].innerText !== "") { let date = /((\d+)[^\d]+(\d+)|(\d{4})).+/gm.exec(onair[1].innerText); if(date !== null) { if(date[4] === undefined) { let today = new Date(); let yyyy = today.getFullYear(); let mm = (date[2].length > 1 ? "" : "0") + date[2]; let dd = (date[3].length > 1 ? "" : "0") + date[3]; filename = yyyy + mm + dd; } else { filename = date[4]; } } } } let title = document.querySelectorAll('span[class^="titles_seriesTitle"]'); if(title.length > 0 && title[0].innerText !== "") filename += (filename.length === 0 ? "" : " ") + title[0].innerText; let episode = document.querySelectorAll('span[class^="titles_title"]'); if(episode.length > 0 && episode[0].innerText !== "") filename += " " + episode[0].innerText; */ filename = Convert(filename); let hls = await TverVideoDownload(json.streaks.projectID, json.streaks.videoRefID); if ('' !== hls) SetResult('HLS copy', `${hls}\n${filename}\n`, "right", "video"); else SetResult('error', '', "right", "video"); SetResult(filename, filename, "right", "title"); TverVideo(filename); if(json.id !== undefined) { let img = `https://statics.tver.jp/images/content/thumbnail/episode/xlarge/${json.id}.jpg`; SetResult('<a href="' + img + '" download="' + filename + '"><img src="' + img + '" width="300px"></a>', img, "right", "thum"); } console.log(filename); } function Tver() { let id = document.location.href; if (id.match(/([^\/\?$]+)(?:$|\?)/)) id = RegExp.$1; else id = ""; if (id === "") { console.log("not detected"); } let xmlhttp = new XMLHttpRequest(); let url = `https://statics.tver.jp/content/episode/${id}.json`; xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == XMLHttpRequest.DONE) { if (xmlhttp.status == 200) { TverInfo(JSON.parse(xmlhttp.responseText)); } else if (xmlhttp.status == 400) { console.log('There was an error 400'); } else { console.log('something else other than 200 was returned'); } } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } function NicoLive() { let onair = $("*[class^='___onair-time___']")[0].getAttribute("datetime").replace(/(\d+)-(\d+)-(\d+).*/g, "$1$2$3"); let title = document.getElementsByTagName("h1"); if(title.length == 1) title = title[0].innerText; else title = $("*[class^='___title___']")[0].innerText; title = Convert(onair + " " + title); SetResult(title, title, "right", "title"); } function NicoArchive() { let onair = document.querySelector('time').getAttribute("datetime").replace(/(\d+)-(\d+)-(\d+).*/g, "$1$2$3"); let title = document.querySelector('.fs_xl.fw_bold').textContent; title = Convert(onair + " " + title); SetResult(title, title, "right", "title"); } function Main() { if(typeof(jQuery) == 'undefined') { let jquery = document.createElement('script'); jquery.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'; document.body.appendChild(jquery); setTimeout(Main, 100); return; } let url = document.location.href; let extractFunc = null; if (/tver.jp/gi.test(url)) extractFunc = Tver; else if (/live2?\.nicovideo\.jp/gi.test(url)) extractFunc = NicoLive; else if (/nicovideo\.jp\/watch/.test(url)) extractFunc = NicoArchive; extractFunc(); } Main(); })();