Greasy Fork is available in English.

動畫瘋下載器

取得動畫的m3u8網址

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name        動畫瘋下載器
// @namespace   
// @description 取得動畫的m3u8網址
// @version     1.5.1
// @author      maple3142/XPRAMT
// @match       https://ani.gamer.com.tw/animeVideo.php?sn=*
// @connect     ani.gamer.com.tw
// @require     https://cdn.jsdelivr.net/npm/m3u8-parser@4.2.0/dist/m3u8-parser.min.js
// @require     https://unpkg.com/xfetch-js@0.3.4/xfetch.min.js
// @require     https://unpkg.com/gmxhr-fetch@0.1.0/gmxhr-fetch.min.js
// @grant       GM_xmlhttpRequest
// @grant       unsafeWindow
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

(function () {
	'use strict';
	var $ = jQuery;
    const select = (DOM) => document.querySelector(DOM);
//////////////////////////函式//////////////////////////
    //注入樣式
    function styleInject(css, ref) {
	  if ( ref === void 0 ) ref = {};
	  var insertAt = ref.insertAt;

	  if (!css || typeof document === 'undefined') { return; }

	  var head = document.head || document.getElementsByTagName('head')[0];
	  var style = document.createElement('style');
	  style.type = 'text/css';

	  if (insertAt === 'top') {
	    if (head.firstChild) {
	      head.insertBefore(style, head.firstChild);
	    } else {
	      head.appendChild(style);
	    }
	  } else {
	    head.appendChild(style);
	  }

	  if (style.styleSheet) {
	    style.styleSheet.cssText = css;
	  } else {
	    style.appendChild(document.createTextNode(css));
	  }
	}
    //解析m3u8
    async function parse_playlist(){
        const req = playlist.src;
        const response = await fetch(req)
        const text = await response.text();
        const urlPrefix = req.replace(/playlist.+/, ''); //m3u8URL前綴
        const m3u8List = text.match(/=\d+x\d+\n.+/g);
        let m3u8_dict = {};
        title_display.text('點擊下方複製連結');
        Name=document.title.replace(" 線上看 - 巴哈姆特動畫瘋","").replace(/[\/:*?"<>|]/g, '_');
        for (let i = 0; i < m3u8List.length; i++) {
            let key = m3u8List[i].match(/=\d+x\d+/)[0];
            key = key.match(/x\d+/)[0].substring(1);//解析度作为key
            let m3u8_url = m3u8List[i].match(/.*chunklist.+/)[0];//提取m3u8文件
            m3u8_url = urlPrefix + m3u8_url;//组成完整的m3u8URL
            let videolink=$('<a>').addClass('anig-tb').text(key+'p').on('click', function (){
                navigator.clipboard.writeText(m3u8_url+'@'+Name);
                title_display.text('複製成功!');
                setTimeout(function(){
                    title_display.text('點擊下方複製連結');
                },500);
            });
            m3u8container.append(videolink);//添加按鈕
        }
    }
    //獲得m3u8
    function getPlaylist() {
        var ad=1;
        const req = `https://ani.gamer.com.tw/ajax/m3u8.php?sn=${AniVideoSn}&device=${DeviceID}`;
        async function loop() {
            title_display.text('等待廣告...');
            const response = await fetch(req);
            playlist = await response.json();
            if(JSON.stringify(playlist).includes('https')){//判斷是否有廣告,
                ad=0;
                clearInterval(it1);//停止loop
            }
        }
        function NoAd() {
            if(ad==0){
                clearInterval(it2);
                parse_playlist()//解析m3u8
            }
        }
        loop();
        const it1 = setInterval(loop, 3000);
        const it2 = setInterval(NoAd, 100);
    }
    //獲得裝置ID
    async function getDeviceId() {
        const req = 'https://ani.gamer.com.tw/ajax/getdeviceid.php';
        const response = await fetch(req);
        const data = await response.json();
        DeviceID = data.deviceid;
        getPlaylist();//獲得m3u8
    }
//////////////////////////Main//////////////////////////
    //宣告
    var Name;
    var AniVideoSn = animefun.videoSn;
    var DeviceID;
    var playlist;
    var css = ".anig-ct {\r\n\tdisplay: flex;\r\n\twidth: 100%;\r\n\tmargin: 5px;\r\n}\r\n\r\n.anig-tb {\r\n\tdisplay: inline-block;\r\n\tpadding: 5px;\r\n\tbackground: #00B4D8;\r\n\tcolor: #FFF;\r\n\tmargin-right: 5px;\r\n\tborder: 1px solid #BBB;\r\n}\r\n\r\n.tdn{\r\n\ttext-decoration: none;\r\n}\r\n";
    //顯示按鍵
	var title_display = $('<div>').addClass('anig-tb').text('載入中...');
	var m3u8container = $('<div>').addClass('anig-ct');
	$('.anime_name').append($('<div>').addClass('anig-ct').append(title_display)).append(m3u8container);

    // 取得帶有 data-ani-video-sn 屬性的<a>標籤
    var links = document.querySelectorAll('a[data-ani-video-sn]');

    // 新增點擊事件監聽器
    links.forEach(function(link) {
        link.addEventListener('click', function(event) {
            AniVideoSn = this.getAttribute('data-ani-video-sn');
            m3u8container.empty();
            title_display.text('載入中...');
            getDeviceId();//獲得裝置ID
        });
    });

    //開始
    getDeviceId();//獲得裝置ID
	styleInject(css);//注入樣式
}());