Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Программы » Opera на движке Presto (часть 27)

Модерирует : gyra, Maz

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

Alex_Qwerty

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
 
 
// ==UserScript==
// @include *.youtube.com/*
// @include *.youtube-nocookie.com/*
// @include *.youtubeeducation.com/*
// ==/UserScript==
(function(opera){
 
    var ScriptName = 'youtube_fuck_html5.js v22';
 
    var conf = {
          relatedVideos : false   // click title if not works
        , blockPlayerBase : true
        , videoQuality : 'auto'   // highres hd1440 hd1080 hd720 large medium small tiny auto
        , autoplay : 0            // 1 0; not in background; not in iframe
        , del43 : true            // remove format 43 (webm 640x360); can help switching to 720
        , useManifest: false      // buggy
        , noSubtitles: true       // they don't works
        , swf : 'https://s.ytimg.com/yts/swfbin/player-vfljf_kbO/watch_as3.swf'    // dead
        , deleteCookies: [
            //'VISITOR_INFO1_LIVE'    // messes with signatures
        ]
        , replaceCookies: {
        }
        , addParams: {
              theme: 'dark'        // dark, light
            , color: 'red'        // red, white
            //, hl: 'en'
        }
        //, wmode : 'direct'    // window, direct, opaque, transparent, gpu https://helpx.adobe.com/ru/flash/kb/flash-object-embed-tag-attributes.html
    }
 
/*
Need something against crossdomain.xml and watch_as3.swf
 
Filters for Proxomitron:
 
[Patterns]
Name = "youtube dash manifest fix"
Active = TRUE
URL = "manifest.googlevideo.com(:443|)/api/manifest/dash/"
Limit = 256
Match = "(<SegmentList>)\1(<SegmentURL media="\2")\3"
Replace = "\1<Initialization sourceURL="\2"/>\3"
 
[HTTP headers]
In = FALSE
Out = TRUE
Key = "Accept-encoding: youtube no gzip, enable filtering"
URL = "manifest.googlevideo.com(:443|)/$FILTER(True)"
 
 
 
 
[HTTP headers]
In = FALSE
Out = TRUE
Key = "URL: youtube crossdomain.xml"
URL = "([^/]++.|)(youtube(-nocookie|education|).com|ytimg.com|googlevideo.com)(:443|)/crossdomain.xml$RDIR(http://local.ptron/crossdomain.xml)"
 
In = FALSE
Out = TRUE
Key = "URL: youtube watch_as3.swf"
URL = "s.ytimg.com(:443|)/yts/swfbin/player-*watch_as3.swf$RDIR(http://local.ptron/watch_as3.swf)"
 
In = FALSE
Out = TRUE
Key = "Accept-encoding: youtube no gzip, enable filtering"
URL = "manifest.googlevideo.com(:443|)/$FILTER(True)"
 
 
 
crossdomain.xml (put in Proxomitron\html\):
 
<?xml version="1.0"?>
<cross-domain-policy>
  <allow-access-from domain="*" />
</cross-domain-policy>
 
*/
 
    window.spf = {};
 
 
    var sts, pr, formats={}, itags=[];
 
    document.createElement("video").constructor.prototype.canPlayType = function(type){return ""};    // disable HTML5
 
    var showConf = true;
    function log(str){
        opera.postError(ScriptName + (str?': '+str:'')+(showConf?'\nconf='+JSON.stringify(conf):''));
        showConf = false;
    }
 
    //https://learn.javascript.ru/cookie
    function setCookie(name, value, options) {options = options || {};var expires = options.expires;if (typeof expires == "number" && expires) {var d = new Date();d.setTime(d.getTime() + expires * 1000);expires = options.expires = d;}if (expires && expires.toUTCString) {options.expires = expires.toUTCString();}var updatedCookie = name + "=" + value;for (var propName in options) {updatedCookie += "; " + propName;var propValue = options[propName];if (propValue !== true) {updatedCookie += "=" + propValue;}}document.cookie = updatedCookie;}
    function deleteCookie(name, options) {options=options||{}; options.expires=-1; setCookie(name, "", options)}
 
    function deleteCookieForDomains(name, domain){
        deleteCookie(name,{domain:domain});
        deleteCookie(name,{domain:domain.replace(/^www\./,'.')});
        deleteCookie(name,{domain:domain.replace(/^www\./,'')});
    }
 
    if (conf.deleteCookies) for (var i=0; i<conf.deleteCookies.length; i++) {
        deleteCookieForDomains(conf.deleteCookies[i],location.hostname);
    }
 
    if (conf.replaceCookies) for (var prop in conf.replaceCookies) if (conf.replaceCookies.hasOwnProperty(prop) && typeof(conf.replaceCookies[prop]) == 'string') {
        deleteCookieForDomains(prop,location.hostname);
        setCookie(prop, conf.replaceCookies[prop], {expires:'Tue, 15-Jan-2030 03:14:07 GMT', path:'/'})
    }
 
 
/*
/s/player/4fbb4d5b/player_ias.vflset/ru_RU/base.js
*/
 
 
    //opera.postError(ScriptName);
    opera.addEventListener("BeforeScript",function(e){
        if (e.element.src.match(/\/player.*?\/base\.js/)) {
            opera.postError('base.js: '+ e.element.src);
            sts = e.element.text.match(/signatureTimestamp[\s:=]+(\d+)[,;}]/);
            sts=sts&&sts[1];
            if (sts) {
                log('player: '+e.element.src+'\nsts='+sts+'\nUA='+navigator.userAgent);
                if (conf.blockPlayerBase) {
                    if (window.canBlockPlayerBase) {
                        var decf = e.element.text.match(/=function\(a\){(a=a.split\(""\)[^}]*?;return a.join\(""\))};/);
                        decf = decf && decf[1];
                        var deco = decf && decf.match(/([\w$_]+)\.[\w$_]+\(a,\d+\);/);
                        deco = deco && e.element.text.match(new RegExp('var '+deco[1].replace(/\$/,'\\$')+'={[\\w$_]+:function\\(a[\\s\\S]*?};','m'));
                        deco = deco && deco[0];
                        if (decf && deco) {
                            decodeSignature = new Function('a', deco+decf);
                            e.preventDefault();
                            log('blocked player base.js: '+e.element.src);
                        } else {
                            log("error: can't get decoder from player base.js\ndeco="+deco+'\ndecf='+decf)
                        }
                        fuckn = e.element.text.match(/=function\(a\){(var b=a.split\(""\)[\s\S]*?return b.join\(""\))};/m);
                        if (fuckn) {
                            log('found fuck n function');
                            fuckn = new Function('a', fuckn[1]);
                        } else {
                            log('fuck n function is not found!');
                        }
                    } else {
                        log('blockPlayerBase requires blockYoutubeScripts in youtube_fix.js');
                    }
                } else {
                    e.element.text = e.element.text.replace('=function(a){a=a.split("")','=decodeSignature=function(a){a=a.split("")')
                        .replace('=function(a){var b=a.split(""),c=','=fuckn=function(a){var b=a.split(""),c=');
/*
hha=function(a){var b=a.split(""),c=[function(d,e){e=(e%d.length+d.length)%d.length;d.splice(0,1,d.splice(e,1,d[0])[0])},
*/
 
                }
            }
        }
    },false);
 
    function getField(obj) {
        var tmp = obj;
        if (tmp) for (var i=1; i<arguments.length; i++) {
            tmp = tmp[arguments[i]];
            if (!tmp) break;
        }
        return tmp;
    }
 
    function xhr(url, method, post, xml, headers){
        var x = new XMLHttpRequest();
        x.open(method || 'GET', url, false);
        if (headers) for (var i=0; i<headers.length; i++) x.setRequestHeader(headers[i][0], headers[i][1]);
        x.send(post);
        return xml?x.responseXML:x.responseText;
    }
 
    function splitKV(str, o) {
        o = o || {};
        var tmp;
        var re = /([\da-z_]+)=([^&]*)/gi;
        while ( (tmp = re.exec(str))!==null ) { o[tmp[1]] = decodeURIComponent(tmp[2].replace(/\+/g,' '));    }
        return o;
    }
 
    function concatKV(obj){
        var tmp = [];
        for (var n in obj) {
            var value = obj[n]; //typeof(obj[n])=='object'? JSON.stringify(obj[n]) : obj[n];
            tmp.push(n+'='+encodeURIComponent(value).replace(/,/g,'%2C') );
        }
        return tmp.join('&');
    }
 
    var onceFix = true;
    function fix(str){
        var tmp = str.split(',');
        for (var i=tmp.length-1; i>=0; i--) {
            var obj = splitKV(tmp[i]);
            del(obj,['xtags']);
            if (fuckn) obj.url = obj.url.replace(/&n=([\w_-]+)/,function(a,b){return '&n='+fuckn(b)});
            if (conf.del43 && obj.itag==43) {
                tmp.splice(i,1);    // del
                log('removed format 43')
            } else if (obj.clen==0 && obj.url.indexOf('live=1')==-1) {
                tmp.splice(i,1);    // del
                log('removed clen==0 itag='+obj.itag);
            } else if (obj.s) {
                obj.itag = parseInt(obj.itag);
                if (formats[obj.itag]) {
                    obj.url = formats[obj.itag];
                    delete obj.s;
                } else if (!window.decodeSignature) {
                    if (onceFix) onceFix = log('error: no decodeSignature()')
                    return str;
                } else {
                    obj.url += '&'+(obj.sp||'signature')+'='+decodeSignature(unescape(obj.s));
                    delete obj.s;
                }
                tmp[i] = concatKV(obj);
            }
        }
        return tmp.join(',');
    }
 
    function del(obj,arr){ for (var d in arr) delete obj[arr[d]]; }
    function set(obj,arr){ for (var d in arr) obj[d]=arr[d]; }
    function setNew(obj,arr){ for (var d in arr) if (typeof(obj[d])=='undefined') obj[d]=arr[d]; }
 
    if (location.pathname.indexOf('/embed/')==0 || location.pathname=='/watch' && window==window.top) document.addEventListener('DOMContentLoaded',function(){
        var errMsg = document.querySelector('#unavailable-message');
        var div;
        var selectors = ['div.html5-video-player', 'div#player-api', 'div#player'];
        for (var i=0,s; s=selectors[i]; i++) if (div = document.querySelector(s)) break;
        if (!div) {
            log('player div not found');
        } else {
            log('found div:'+(div.id?' id="'+div.id+'"':'') + (div.className?' class="'+div.className+'"':''));
            if (!sts) log('warning: sts from /player-./base.js not found! Check content blocker.');
            div.classList.remove('off-screen-target');
            div.innerHTML = '<br><br>'+ScriptName;
            var u = document.querySelector('div#player-unavailable');
            if (u) u.parentNode.removeChild(u);
            var id = (''+location).match(/\/embed\/([\da-z_-]{11})/i) || (''+location).match(/[&?]v=([\da-z_-]{11})/i);
            id = id&&id[1];
            if (!id) {
                div.innerHTML += ' - no video id';
                return log('no video id');
            }
 
            var bg = 'https://i.ytimg.com/vi/'+id+'/hqdefault.jpg';
            var info, infoLength, status, reason, proceed;
            function gvi(data) {
                //var url = '/get_video_info?html5=1&asv=3&ps=default'+(sts?'&sts='+sts:'')+'&video_id='+id+(data||'');
                //info = xhr(url);
                //if (info.indexOf('status=')==-1) info = xhr(url);    // second try
                var crap = JSON.stringify({"videoId":id, "context": {"client": {"clientName": "WEB_EMBEDDED_PLAYER","clientVersion": "1.20210616.1.0"}}});
                var crapHeaders = [["X-Youtube-Client-Name","56"], ["X-Youtube-Client-Version","1.20210615.1.0"] ];
                info = xhr('/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', 'POST', crap, false, crapHeaders)
                infoLength = info.length;
                //info = splitKV(info);
                info = JSON.parse(info);
                //if (info.player_response) info.player_response = JSON.parse(info.player_response);
                status = getField(info, 'playabilityStatus', 'status') || getField(info, 'playabilityStatus', 'status');
                if (status) status=status.toLowerCase();
                var ps = getField(info, 'playabilityStatus') || info.playabilityStatus || {};
                reason = ps.reason || getField(ps, 'errorScreen', "playerErrorMessageRenderer", "reason", "simpleText");
                proceed = getField(ps, 'errorScreen', 'playerErrorMessageRenderer', 'proceedButton', 'buttonRenderer', 'text', 'simpleText');
 
            }
            gvi();
            if (status=="unplayable") {
                if (reason.indexOf("youtube.com/watch")!=-1
                    || (proceed&&proceed.indexOf('YouTube')!=-1)
                ) {
                    opera.postError([ScriptName, 'error',reason,proceed,status])
                    var page = xhr('/watch?v='+id);
                    var tmp = page.match(/var ytInitialPlayerResponse\s*=\s*({.*?});/)
                        || page.match(/ytplayer.config = ({.*?});ytplayer/);
                    tmp = tmp && JSON.parse(tmp[1])
                    if (tmp.args) tmp=tmp.args;
                    if (tmp) {
                        info = tmp;
                        //if (info.player_response) info.player_response = JSON.parse(info.player_response);
                        status = getField(info, 'playabilityStatus', 'status') || getField(info, 'playabilityStatus', 'status');
                        if (status) status=status.toLowerCase();
                        reason = getField(info, 'playabilityStatus', 'reason') || getField(info, 'playabilityStatus', 'reason');
                    }
//alert(JSON.stringify(tmp,null,'\t'))
 
                } else {
                    gvi('&eurl=https://www.google.com/');
                }
            }
 
            if (status!='ok') {
                div.innerHTML = '<br><br>'+reason;
                return log('reason: '+reason);
            }
 
            log(JSON.stringify({cbr:info.cbr, cbrver:info.cbrver, cbrand:info.cbrand, infoLength:infoLength}));
            if (!conf.relatedVideos) delete info.rvs;
            del (info, ['ppv_remarketing_url','remarketing_url', 'allowed_ads', 'survey_smartpixel_url']);
            pr = info//.player_response;
//alert(JSON.stringify(info,null,'\t'));
            if (pr) {
                var sd = pr.streamingData || info.streamingData || {};
                var tmp = sd.formats;
                if (tmp) for (var i=0; i<tmp.length; i++) formats[parseInt(tmp[i].itag)]=tmp[i].url;
                tmp = sd.adaptiveFormats;
                if (tmp) for (var i=0; i<tmp.length; i++) formats[parseInt(tmp[i].itag)]=tmp[i].url;
                // manifests don't work?
                if (!info.dashmpd) info.dashmpd = sd.dashManifestUrl;
                //if (!info.hlsvp) info.hlsvp = sd.hlsManifestUrl;
                //var st = getField(pr, 'playabilityStatus', 'status') || getField(info, 'playabilityStatus', 'status');
                //var re =
                //if (st=="UNPLAYABLE") return div.innerHTML = '<br><br>' + pr.playabilityStatus.reason;
                if (status=="unplayable") return div.innerHTML = '<br><br>' + reason;
            }
 
 
            //var eventid = (info.url_encoded_fmt_stream_map||info.adaptive_fmts).match(/ei%3D([^%]+)/)[1];
            var crap = {
                  storyboard_spec: getField(pr, 'storyboards', 'playerStoryboardSpecRenderer', 'spec')
                      || "https://i9.ytimg.com/sb/LpWKhuvcXGU/storyboard3_L$L/$N.jpg?sqp=ovOX_wMGCMLdv58F|48#27#100#10#10#0#default#rs$AOn4CLCZ4iJXVfCkSXp3QGpGckl5vCoKAA|80#45#76#10#10#1000#M$M#rs$AOn4CLCLFHKsZ4N97Z2y-gYuQauK7NH3SQ|160#90#76#5#5#1000#M$M#rs$AOn4CLDLKWOa64VAWs_XCvNKMPnOd1xWCQ"
                , token: 'fuck'
                , length_seconds: getField(pr, 'videoDetails', 'lengthSeconds')
                , title: getField(pr, 'videoDetails', 'title')
                , video_id: getField(pr, 'videoDetails', 'videoId')
            }
//alert(JSON.stringify(crap,null,'\t'))
            setNew(info, crap);
 
 
            if (conf.noSubtitles) {
                del(info, ['ttsurl','caption_tracks','caption_audio_tracks', 'cc_asr', 'cc3_module', 'caption_translation_languages', 'cc_font']);
                info.has_cc = 'False';
            } else {
                var tmp = JSON.parse(info||'{}');
                if (tmp.captions) {
                    tmp = tmp.captions.playerCaptionsTracklistRenderer.captionTracks
                }
 
            }
            if (conf.del43 && info.fmt_list) info.fmt_list = info.fmt_list.replace('43/640x360,','');
            if (conf.addParams) set(info, conf.addParams);
            if (conf.videoQuality) info.vq = conf.videoQuality;
            info.autoplay = conf.autoplay && !document.hidden && window==window.top && 1 || 0;
 
            if (info.url_encoded_fmt_stream_map) info.url_encoded_fmt_stream_map = fix(info.url_encoded_fmt_stream_map);
            if (info.adaptive_fmts) info.adaptive_fmts = fix(info.adaptive_fmts);
 
            function fix2(dest, arr, clean) {
                if (info[dest] || !arr) return;
                info[dest] = arr;
                for (var obj,i=arr.length-1; obj=arr[i]; i--) {
                    if (conf.del43 && obj.itag==43 || obj.type=='FORMAT_STREAM_TYPE_OTF' || obj.projectionType!="RECTANGULAR") {
                        arr.splice(i,1);    // del
                    } else {
                        obj.itag = parseInt(obj.itag);
                        itags.push(obj.itag);
                        var repl = { contentLength:'clen', mimeType:'type', lastModified:'lmt', qualityLabel:'quality_label' }
                        for (var prop in repl) if (obj.hasOwnProperty(prop)) obj[repl[prop]] = obj[prop] || obj[repl[prop]];
                        obj.clen = obj.clen || obj.contentLength;
                        obj.type = obj.mimeType || obj.type;
                        obj.size = obj.size || obj.width && obj.width+'x'+obj.height;
                        obj.projection_type = 1;
                        if (obj.cipher||obj.signatureCipher) {
                            splitKV(obj.cipher||obj.signatureCipher, obj);
                        }
                        if (obj.initRange) obj.init = obj.initRange.start+'-'+obj.initRange.end;
                        if (obj.indexRange) obj.index = obj.indexRange.start+'-'+obj.indexRange.end;
                        if (obj.s) {
                            if (!window.decodeSignature) {
                                if (onceFix) onceFix = log('error: no decodeSignature()')
                                return;
                            } else {
                                obj.url += '&'+(obj.sp||'signature')+'='+decodeSignature(unescape(obj.s));
                                delete obj.s;
                            }
                        }
                        del(obj, ['cipher','signatureCipher','initRange','indexRange','colorInfo']);
                        if (clean) for (var prop in obj) if (obj.hasOwnProperty(prop)) {
                            if (prop!='itag'&&prop!='fallback_host'&&prop!='url'&&prop!='type'&&prop!='quality') delete obj[prop];
                        }
                        arr[i] = concatKV(obj);
                    }
                }
            }
 
            delete info.url_encoded_fmt_stream_map;
            delete info.adaptive_fmts;
            fix2('url_encoded_fmt_stream_map', getField(info, 'streamingData', 'formats'), true);
            fix2('adaptive_fmts', getField(info, 'streamingData', 'adaptiveFormats'));
 
            if (!info.fmt_list) {
                var tmp2 = [];
                if (~itags.indexOf(22)) tmp2.push('22/1280x720');    // order!
                if (~itags.indexOf(43)) tmp2.push('43/640x360');
                if (~itags.indexOf(18)) tmp2.push('18/640x360');
                info.fmt_list = tmp2.join(',');
            }
 
            if (info.dashmpd) {
                info.dashmpd = info.dashmpd.replace(/\/s\/([\dA-F.]+)/,function(a,s){return '/signature/'+decodeSignature(unescape(s))});
                if (conf.useManifest) del(info, ['fmt_list', 'url_encoded_fmt_stream_map', 'adaptive_fmts']);
            }
            set(info, {no_stats:1, allow_embed:1, no_get_video_log:1, rmkt:0, rtl:0, ad3_module:0, ad_preroll:0, enable_cardio:0
                , enable_cardio_before_playback:0, advideo:0, skl:1
                });
            del(info, ['watch_next_response']);    // for some videos
            del(info, ['fflags']);
//alert(JSON.stringify(info,null,'\t'));
            info = concatKV(info);
//alert(info);
            var wmode = conf.wmode ? 'wmode="'+conf.wmode+'"' : '';
            div.innerHTML = '<embed src="'+conf.swf+'" flashvars="'+info+'" '+wmode+' style="background: url('+bg+') center no-repeat" type="application/x-shockwave-flash" width=100% height=100% allowfullscreen="true" allowscriptaccess="always" bgcolor="#000000" />'
        } // !div
    },false);
 
})(opera)
 


Всего записей: 2144 | Зарегистр. 09-09-2006 | Отправлено: 14:23 04-01-2020 | Исправлено: Alex_Qwerty, 14:53 08-10-2021
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Программы » Opera на движке Presto (часть 27)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.Board
© Ru.Board 2000-2020

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru