Sleazy Fork is available in English.

Japonx 字幕&视频 下载(支持PotPlayer播放)

下载 japonx 的字幕和视频。

As of 25.03.2019. See ბოლო ვერსია.

// ==UserScript==
// @name        Japonx 字幕&视频 下载(支持PotPlayer播放)
// @description 下载 japonx 的字幕和视频。
// @version     4.3.13
// @author      ThisAV
// @homepage    https://greasyfork.org/zh-CN/users/122964
// @namespace   https://greasyfork.org/users/122964
// @feedback    https://greasyfork.org/en/scripts/372676/feedback
// @connect     japronx.com
// @connect     japonx.net
// @connect     japonx.vip
// @connect     japonx.tv
// @connect     japonx.me
// @include     http*://japonx.net/portal/index/detail/id/*
// @include     http*://japonx.vip/portal/index/detail/id/*
// @include     http*://japonx.tv/portal/index/detail/id/*
// @include     http*://japonx.me/portal/index/detail/id/*
// @include     http*://*.japonx.net/portal/index/detail/id/*
// @include     http*://*.japonx.vip/portal/index/detail/id/*
// @include     http*://*.japonx.tv/portal/index/detail/id/*
// @include     http*://*.japonx.me/portal/index/detail/id/*
// @run-at      document-idle
// @require     http://cdn.staticfile.org/jquery/2.1.4/jquery.min.js
// @require     https://greasyfork.org/scripts/373130/code/ProtocolCheck.js?version=635816
// @icon        https://www.japonx.tv/favicon.ico
// @grant       GM_addStyle
// @grant       unsafeWindow
// @grant       GM_setClipboard
// @grant       GM_xmlhttpRequest
// @grant       GM_openInTab
// ==/UserScript==

(function(){
    'use strict';
    var urls=location.href,
        host=location.hostname,
        PageId=location.href.replace(/.+\/id\/(\d+).html/i,'$1'),
        VideoID=$('dt:contains(番號)').next().text(), //番号
        VttLanguage=$('dt:contains(字幕)').next().text(),//字幕语言类型
        VideoUrl,
        VideoDownload=false,
        VideoSubUrl, PlayServer='p',
        HidePic="http://p1.img.cctvpic.com/photoAlbum/templet/special/PAGE9dhkRStLqPhmlDLwNw6D180702/ELMTKZGgi45inXjtvdDG1eNV180705_1531386463.png", //隐藏图片时替代的图片
        webTitle=document.title='【'+VideoID+'】'+document.title,
        $btnDiv = $('#d-btn'),
        $nextBtn = $('<a>').attr({'class':'btnC','href':"https://"+host+"/portal/index/detail/id/"+(Number(PageId)+1)+".html"}).text('下一页'),
        $M3U8Btn = $('<a class="d-btn">').css({'color':'blue','width':'100px','font-weight':'bold'}).attr({'id':'m3u8'}),
        $zmBtn = $('<a class="btnC zm" style="color:#ccc;" href="javascript:void(0);">无字幕文件</a>'),
        $PotBtn = $('<a class="btnC PotPlayer">').css({'color':'black'}).text('Potplayer'),
        $ImgBtn = $('<a class="btnC HideImg">').text('IMG');

    $(document).scrollTop($('#contents-inline').offset().top);

    $btnDiv.append($nextBtn, $M3U8Btn, $zmBtn, $PotBtn, $ImgBtn);
    $('.d-btn.download').hide();//隐藏下载按钮

    var JaPronX={
        CheckUrl : function(url, callback, onerror){
            GM_xmlhttpRequest({
              url:url,
              headers: {
                'Host':'japronx.com',
                'Content-Type': 'application/x-www-form-urlencoded'
              },
                method:'head',
                synchronous:true,
                ontimeout:10000,
                onload:callback,
                onerror:onerror||function(e){
                    if(url.search('.mp4')>-1&&e.status==0) {
                        $M3U8Btn.attr({'href':url,'target':'blank','download':VideoID+'.mp4'}).text('服务器无响应,请求失败').css({'width':'250px','color':'red'});
                    }
                    console.log('CheckUrl error:', e.status, url, e);
                }
            });
        },
        CheckVTT : function(){
            if(VttLanguage=='無') {
                layer.tips('当前视频无字幕', $('dt:contains(字幕)').next().find('a'),{
                    tips: ['2', '#ff0000'],
                    tipsMore: true,
                    time: 0
                });
            }
        },
        HideImg : function(ctrl){
            var logo=HidePic, t;
            if(ctrl) {
                $('img[src*="/upload/admin/"]').each(function(){
                    var obj=this;
                    $(this).attr({'data-src':this.src,'src':logo}).hover(function(){
                        t=setTimeout(function(e){obj.src=$(obj).data('src')}, 2000);
                    },function(){
                        clearTimeout(t);
                        this.src=logo;
                    });
                });
            } else {
                $('img[src*="'+logo+'"]').each(function(){
                    this.src=$(this).data('src');
                });
            }
        }
    }

    $M3U8Btn.click(function(){
        var m3u8Url=this.href;
        if(this.href) {
            GM_setClipboard(this.href);
            layer.msg('已复制 M3U8 地址', {
                time: 0 //不自动关闭
                ,btn: ['复制番号','刷新 M3U8', '关闭']
                ,yes: function(index){
                    layer.close(index);
                    if(VttLanguage=='無') VideoID='【无字幕】'+VideoID;
                    GM_setClipboard(VideoID);
                    layer.msg('已复制番号');
                },
                btn2: function(index){
                    layer.close(index);
                    layer.msg('正在刷新 M3U8 地址');
                    ajaxGetID();
                }
            });
        }
        return false;
    });


    var HideText=$('#wrap-slider, .wrap-header, #wrap-footer-bottom, .js-ajax-delete, h1, h2, .tx-comment, #works, .desc>:not(#d-btn)');  //干净模式
    $ImgBtn.dblclick(function(){
        if(!localStorage['HideText']) {
            localStorage['HideText']=true;
            layer.tips('已开启干净模式', '.HideImg');
            HideText.hide();
        } else {
            layer.tips('已关闭干净模式', '.HideImg');
            delete localStorage['HideText'];
            HideText.show();
        }
    }).click(function(){
        if(!localStorage['HideImg']) {
            layer.tips('已开启图片隐藏', '.HideImg');
            localStorage['HideImg']=true;
            JaPronX.HideImg(true);
        } else {
            layer.tips('已关闭图片隐藏', '.HideImg');
            delete localStorage['HideImg'];
            JaPronX.HideImg(false);
        }
    });
    if(localStorage['HideText']) HideText.hide();
    if(localStorage['HideImg']) JaPronX.HideImg(true);

    GM_addStyle('#JaPonxTool{position:absolute;right:280px;top:20px;} .btnC{cursor:pointer;height:42px;font-size:18px;border:1px solid #d7dadb;padding:8px;margin-left:5px;border-radius:6px;display:inline-block!important;color:#000;background:#fff;}');

    if(0) $btnDiv.append('<a class="d-btn sub" target="_blank" href="https://'+host+'/portal/index/ajax_get_js.html?id='+PageId+'">Ajax</a>');
    $('.desc>dt:contains(番號)').click(function(){
        GM_openInTab('http://www.javlib.com/cn/vl_searchbyid.php?keyword='+$(this).next().text(),'active')
    });

    $('.desc>dt:contains(番號)').next().click(function(){
        if(VttLanguage=='無') VideoID='【无字幕】'+VideoID;
        GM_setClipboard($(this).text());
        layer.msg('已复制番号');
    });

    var ajaxGetID=function(){
        GM_xmlhttpRequest({
            'url':'/portal/index/ajax_get_js.html?id='+PageId,
            'method':'get',
            //'data' : 'id='+PageId,
            'responseType':'text',
            'async':false,
            'onload' : function(e){
                var s=e.responseText;
                GM_addStyle("dl.desc {width:400px;} #d-btn{width:300px;} #contents-inline dl a:hover{border:1px solid #00aaff;margin:1px!important;} /*.play{margin-right:0px!important;}*/");
                //console.log('GM_xmlhttpRequest: ',e, s);

                //console.log('VideoUrl: ',VideoUrl);

                var Arry=s.split(/\||'\.split\('/i), M3U8_Hash=[], M3U8_MD5, M3U8_Expires, VttData/*字幕上传日期*/, VttHash/*字幕文件 Hash*/;
                $.each(Arry,function(index,val){
                    //console.log(index, val.length, val);
                    switch(val.length) {
                            //M3U8 32位 Hash 提取
                        case 32: M3U8_Hash.push(val);break;
                        case 22: M3U8_MD5=val;break;
                        case 10: if(/\d{10}/.test(val)) M3U8_Expires=val;break;
                        case 8: if(/2\d{7}/.test(val)) VttData=val;break;
                        case 2: if(val=='p2') PlayServer=val;break;
                    }
                });

                //console.log(M3U8_Hash, M3U8_Hash.length, M3U8_MD5, M3U8_Expires, VttData);
                if(!M3U8_MD5) {
                    console.log('获取 M3U8_MD5 失败');
                    $M3U8Btn.text('获取 M3U8_MD5 失败').css({'width':'230px'});
                    setTimeout(ajaxGetID, 2000);
                    return false;
                }

                //字幕
                //if(s.search(/\|vtt\|/im)===-1) $zmBtn = $('<a class="d-btn sub" style="color:#ccc;" href="javascript:void(0);">无字幕文件</a>');
                console.log('M3U8_Hash.length', M3U8_Hash.length);
                switch(M3U8_Hash.length) {
                    case 2:
                        $.each(M3U8_Hash, function(i,Hash){
                            CheckVtt(Hash);
                        });
                        break;
                    case 1:
                        CheckVtt(M3U8_Hash.toString(), 'M3U8');
                        break;
                    case 0:
                        $M3U8Btn.text('未找到资源').css({'width':'150px'});
                }

                function CheckVtt(Hash, HashType){
                    if(HashType) {
                        VideoUrl="https://"+PlayServer+".japronx.com/output/"+Hash+"/index.m3u8?md5="+M3U8_MD5+"&expires="+M3U8_Expires;
                        VideoDown(VideoUrl, 'loop');
                    } else {
                        JaPronX.CheckUrl('https://'+host+'/upload/admin/'+VttData+'/'+Hash+'.vtt',function(e){
                            //console.log(i, Hash, e);
                            switch(e.status) {
                                case 200: //如果有字幕,显示字幕按钮
                                    VideoSubUrl='https://'+host+'/upload/admin/'+VttData+'/'+Hash+'.vtt';
                                    $zmBtn.text('下载字幕').css({'color':'black'}).attr({'download':VideoID+'.vtt', 'href':VideoSubUrl});
                                    break;
                                case 404: //如果没有字幕,校验是否为视频地址
                                    JaPronX.CheckUrl("https://"+PlayServer+".japronx.com/output/"+Hash+"/index.m3u8?md5="+M3U8_MD5+"&expires="+M3U8_Expires,function(e){
                                        //console.log('Video:', Hash, e);
                                        VideoUrl="https://"+PlayServer+".japronx.com/output/"+Hash+"/index.m3u8?md5="+M3U8_MD5+"&expires="+M3U8_Expires;
                                        switch(e.status) {
                                            case 200:
                                                VideoDown(VideoUrl);
                                                break;
                                            default:
                                                console.log('VTT 检测阶段 status:', e.status);
                                        }
                                    });
                                    break;
                                default:
                                    console.log(e.status);
                            }
                        });
                    }
                }

                function VideoDown(VideoUrl, CheckMode){
                    JaPronX.CheckUrl(VideoUrl, function(e){//M3U8
                        //console.log('load: ', e.status, VideoUrl, e);
                        switch(e.status){
                            case 200:
                                $M3U8Btn.attr({'href':VideoUrl, 'target':'blank'}).text('M3U8').css({'width':'100px'});
                                $PotBtn.css({'color':'black'}).attr({'href':'potplayer://'+VideoUrl});
                                layer.tips('M3U8 地址已刷新', '#m3u8',{
                                    tips:1,
                                    tipsMore: true,
                                    time: 60000
                                });

                                t=setInterval(function(){
                                    JaPronX.CheckUrl(VideoUrl, function(e){
                                        console.log('test:',e);
                                        if(e.status==410) {
                                            var newM3U8;
                                            $M3U8Btn.attr({'href':''}).text('链接已失效,点击刷新').css({'width':'230px'}).bind('click', newM3U8 = function(){
                                                layer.msg('正在刷新 M3U8 地址');
                                                $(this).unbind('click', newM3U8);
                                                ajaxGetID();
                                            });
                                            clearInterval(t);
                                        }
                                    });
                                }, 60*1000);
                                JaPronX.CheckVTT();
                                    break;
                            case 404:
                                if(CheckMode=='loop') {
                                    $M3U8Btn.css({'width':'230px'});
                                    var CheckTime=300,
                                        t=setInterval(function(){
                                            $M3U8Btn.text((CheckTime--)+'秒后自动重试').css({'width':'230px'});
                                            if(CheckTime==0) {
                                                clearInterval(t);
                                                ajaxGetID();
                                            }
                                        },1000);
                                } else {
                                    $M3U8Btn.text('404');
                                }
                                break;
                            default:
                                $M3U8Btn.text('获取失败').css({'width':'120px'}).attr({'href':'javascript:location.reload();'});
                                break;
                        }
                    });
                }
            },
            'error' : function(e){
                console.log('$ error:',e);
            }
        });
    }
    ajaxGetID();
})();