player.serieturche.eu-e

Facilitates access to serieturche.eu

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name            player.serieturche.eu-e
// @run-at          document-start
// @namespace       https://github.com/GavinBrelstaff
// @description     Facilitates access to serieturche.eu
// @description:it  Facilita l'accesso a serieturche.eu
// @match           https://player.serieturche.eu/e/*
// @require         https://cdn.jsdelivr.net/npm/[email protected]/dist/video.min.js
// @require         https://cdn.jsdelivr.net/npm/[email protected]/videojs.hotkeys.js
// @grant           none
// @version         2.9.1
// @license         GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// ==/UserScript==

console.clear = () => {}; // protect from console wiping
console.log("*****  IN FRAME ******************************************************************");


window.count=0;
window.code=''; // to contain the parameters
window.code_sub=''; // to contain substitle url
window.subtitles='';


new MutationObserver(async (mutations, observer) => {
    const els = mutations
        .flatMap(e => [...e.addedNodes])
        .filter(e => e.tagName == 'SCRIPT')

    for( var el of els )
    {
        window.count++;
        var safe = false;
        var str = '';

        if( el.onerror )  // new workaround for scripts that fail on purpose
        {
          el.onerror=function()
          {
              console.log('adb: FIXED load adsbygoogle');
          };
          console.log( window.count + 'onerror: ' + el.src + '||' + el.onerror.toString() );
        }


        if( el.src ) // script src
        {
            str = el.src;
            safe = false;
        }
        else // inline script code
        {
            str  = el.innerHTML.substring(0,80).replace(/\s*/g,'');
            if( str.startsWith('if(self!=top){mediaplayerdiv2') )
            {  // create video ready for loading m3u8_url
//             el.innerHTML = el.innerHTML.substr(18).replace('<video','<video controls="true"');
               el.innerHTML = `mediaplayerdiv2.innerHTML =
'<video id="olvideo" controls="true" style="background-color: black; display: block !important;" class="video-js vjs-default-skin lazyload" width="100%" height="100%" crossorigin="anonymous" preload="auto" x-webkit-airplay="allow" controlslist="nodownload" playsinline loading="lazy"><p style="color: white">Aspetta e poi clic sul CAPTCHA ...</p></video>'`;
               safe = true;
            }
            else
            if( str.startsWith('varwaspopplayein=false,') )
            {  // extract any subtitle .ass_url
               window.code_sub = el.innerHTML;
               safe = false;
            }            
            else
            if( str.startsWith('//beforeembed.js') )
            {
               safe = false;
               window.code=el.innerHTML; // trigger to start
            }

        }
        if( ! safe )
        {
           el.remove(); // kill script
           console.log( window.count + 'UNSAFE: ' + str );
        }
        else
           console.log( window.count + ' _SAFE: ' + str );
    }

}).observe(document, {
    childList: true,
    subtree: true,
})


////////////////////////////////////////////////////
// python code: https://github.com/Kodi-vStream/venom-xbmc-addons

function decrypt(str)
{
    str = str.substr(1) // str[1:]
    var j = 0;
    var s2 = '';
    while( j < str.length )
    {
        s2 += '\\u0' + str.substr(j,3); // str[j:(j + 3)]
        j += 3;
    }
    //s2 = decodeURI(s2);
    s2 = JSON.parse('"' + s2 + '"'); // https://www.javaspring.net/blog/how-to-decode-unicode-html-by-javascript/
    return s2
}




window.tries=0;

function random_hexstr(n)
{
  const hexArr='0123456789abcdef'.split(''); // length 16
  var str='';
    for(var i=0; i<n; i++)
    {
        const d = Math.floor(Math.random() * 16);
        str += hexArr[d];
    }
   return(str);
}


// https://sqlpey.com/javascript/how-to-retrieve-dimensions-of-base64-images-in-javascript/
window.fetching = false;

function renderCaptcha( data )
{
  var image = document.getElementById('captcha');
    if( !image )
    {
       image = new Image();
       image.id = 'captcha';
       image.style="position:absolute; left: 0; top: 0; z-index: 100; border:1px solid yellow;"
       image.onload = function(e) {
            const el = e.target; // this
             console.log('image loaded: ' + el.width + ' x ' + el.height );
             console.log('image loaded: Please click');
        };
        image.onerror = function() {
             console.log('image loaded: FAILED ...');
             // restart from here
        };
        image.onclick = function(e) {
            const el = e.target; // this
            if( window.fetching ) {
                console.log('click blocked :' + e.clientX + ', ' + e.clientY );
            }
            else
            {
                console.log('click allowed :' + e.clientX + ', ' + e.clientY );
                window.fetching = true;
                fetch_md5( el.hash_image, e.clientX, e.clientY );
            }
        };
        document.body.append( image );
    }
    image.hash_image = data.hash_image;
    image.src = data.image; // Set source and evoke onload
}

const delay = ms => new Promise(res => setTimeout(res, ms));


async function try_again_image( isec ) {
    try {
        await delay(5000);
        console.log("Waited 5s | isec: " + isec);
        fetch_player_image( );
    } catch (error) {
        console.error(error);
    }
}

async function try_again_md5( hash_image, width, height, isec ) {
    try {
        await delay(5000);
        console.log("Waited 5s | isec: " + isec);
        fetch_md5( hash_image, width, height );
    } catch (error) {
        console.error(error);
    }
}


function fetch_player_image()
{
  console.log('fetch_player_image: ' + window.tries++ );

    fetch('/player/get_player_image.php',
    {
        method: "POST",
        body: JSON.stringify
        ({
          'videoid':  window.videoid, //'34384335',
          'videokey': window.videokey, //'yBnRZTuCOJan',
          'width':    400,
          'height':   400
        }),
        headers: {
          "Content-type": "application/json",
          "Origin": "https://player.serieturche.eu",
          "X-Requested-With": "XMLHttpRequest"
        }
    })
     .then((response) => response.json())
     .then((data) =>
     {
          console.log(data);
          var size=null;
          if( data.success  && data.hash_image )
          {  // extract hash_image, x,y
            try { //  try to retrieve successful click {'x': xval, 'y': yval}
/*
               const coord = localStorage.getItem(data.hash_image);
                  if( coord != null && coord.x && coord.y )
                  {
                    console.log('Retrieved coords: ' + coord.x +'. ' + coord.y);
                    fetch_md5( data.hash_image, coord.x, coord.y ); // skip captcha
                  }
                  else
*/
                renderCaptcha( data );
              } catch (error) {
                  console.error(error);
            }
          } else if( data.try_again && data.try_again == '1')
          {
            console.log('/player/get_player_image.php says TRY AGAIN... ');
            //fetch_player_image();
            try_again_image( data.isec );
          }
      }
    )
}


function fetch_md5( hash_image, x, y ) // from click or algorithm
{
  console.log('fetch_md5: ' + (window.tries++) + ' | coord: ' + x + ',' + y );

    fetch('/player/get_md5.php',
    {
        method: "POST",
        body: JSON.stringify
        ({
        'htoken': '',
        'sh': random_hexstr(40), // 40 char random number as leading zero string
        'ver': '4',
        'secure': '0',
        'adb': window.adbn,
        'v':   window.videokey,
        'token': '',
        'gt': '',
        'embed_from': '0',
        'wasmcheck': 1,
        'adscore': '',
        'click_hash': encodeURIComponent(hash_image), // encodeURIComponent
        'clickx': x,
        'clicky': y
        }),
        headers: {
          "Content-type": "application/json",
          "Origin": "https://player.serieturche.eu",
          "X-Requested-With": "XMLHttpRequest"
        }
    })
     .then((response) => response.json())
     .then((data) =>
     {
          console.log(data);
          var player;
          window.fetching = false; // re-allow clicks
          if( data.try_again && data.try_again == '1')
          {
            console.log('/player/get_md5.php says TRY AGAIN... ');
            //try_again_md5( hash_image, width, height, data.isec );
            try_again_image( data.isec );
          }
          else if( data.obf_link && data.obf_link != '#' )
          {
            console.log('SUCCESS: obf_link: ' + data.obf_link );
            document.getElementById('olvideo').style.visibility = 'visible';
         // localStorage.setItem(hash_image, {'x': x, 'y': y});  // store successful click
            const m3u8_url = "https:" + decrypt( data.obf_link ) + '.mp4.m3u8';
            console.log('m3u8_url: ' + m3u8_url );
            player =videojs('#olvideo', {	plugins: { 	hotkeys: {
                        volumeStep: 0.1,
                        seekStep: 5,
                        enableModifiersForNumbers: false,
                      },
                  },
            });
            player.ready(function()
            {
                if( window.subtitles )
                {
                    const myvideo = document.querySelector('#olvideo > video');
                    if( myvideo )
                    {
                        const track = myvideo.addTextTrack("subtitles", "Italiano", "it");
                        track.mode = "showing";
                        for( cue of window.subtitles )
                        {
                           track.addCue(new VTTCue(cue.start, cue.end, cue.text));
                        }                        
                        console.log(track.cues);
                    }
              }
            });

             player.src({
                src: m3u8_url,
                type: 'application/x-mpegURL'
             });
             
             const mycaptcha = document.getElementById('captcha');
             if(mycaptcha) mycaptcha.remove();
             //document.getElementById('olvideo').style.visibility = "visible"; // make visible
             loadcss();
             
             player.play();
             
             // set tab title <meta property="og:title" content="B B G 01">
             const mytitle = document.querySelector('meta[property="og:title"][content]');
             if( mytitle )   document.title = '❣️ ' + mytitle.getAttribute('content');
             
             // eliminate the dull favicon
             var link = document.querySelector("link[rel~='icon']");
             if (!link) {
                link = document.createElement('link');
                link.rel = 'icon';
                document.head.appendChild(link);
             }
             link.href = document.createElement("canvas").toDataURL("image/x-icon"); // blank image
          }
          else
          {
            console.log('/player/get_md5.php BAD obf_link... ');
            //try_again_md5( hash_image, width, height, data.isec );
            // halt here
          }
     }
   )
}


function loadcss()
{
  const mylink = document.createElement('link');
  mylink.rel = "stylesheet";
  mylink.type = "text/css";
  mylink.href = "https://vjs.zencdn.net/7.19.2/video-js.css";
  document.getElementsByTagName('head')[0].appendChild(mylink);
  const timediv = document.getElementById('timeDiv');
  if( timediv ) timediv.remove();
  const mailto = document.querySelector('a[href^="mailto:"]');
  if( mailto ) mailto.remove();
}


const mypid = setInterval(function() // Polling for window.code parameters
{
  if( window.code && window.code.includes('videoid =') )   {
    // userid = "162759", (adbn)
    // server_referer = "https://player.serieturche.eu/f/yBnRZTuCOJan", (videokey)
    // videoid = "34384335",
    const lineArr = window.code.split('\n');
    for(line of lineArr)
    {
       if( line.includes('userid =') )
             window.adbn = line.replace(/.*userid\s*=\s*"([^"]*)".*/, '$1');
       else
       if( line.includes('videoid = ') )
             window.videoid = line.replace(/.*videoid\s*=\s*"([^"]*)".*/, '$1');
       else
       if( line.includes('server_referer = ') )
             window.videokey = line.replace(/.*server_referer\s*=\s*"https\:\/\/player\.serieturche\.eu\/[e-f]\/([^"]*)",/, '$1');
    }
    console.log('videoid  = ' + window.videoid );
    console.log('videokey = ' + window.videokey );
    console.log('adbn     = ' + window.adbn );

     clearInterval(mypid);
     //tidy up initial graphics
     document.getElementById('body').style.backgroundColor = 'black';
     document.getElementById('olvideo').style.visibility = 'hidden';
     document.querySelector('img[src*=duckduckgogg]').remove();
     fetch_player_image();  // start the fetching algorithm
  }
}, 500); // every 0.5 sec


async function fetchConvert(suburl) {
  console.log('fetchConvert() ');
  try {
    const response = await fetch(suburl,{
        method: "GET",
        headers: {
          "Content-type": "text/json",
          "Origin": "https://player.serieturche.eu",
          "X-Requested-With": "XMLHttpRequest"
          }
        });
        if (!response.ok) throw new Error('Fetch failed');
      const assText = await response.text();
      console.log('assText: ' + assText);
      if( 0 < assText.length ){
           window.subtitles = assToCueArr(assText);
           console.log('window.subtitles:\n' + window.subtitles );
      }
      else
      console.log('window.subtitles  NONE' );
  } catch (error) {
    alert(error.message);
  }
}

function time_str2secs( time_str )
{
  const myArr = time_str.split(':'); // h:mm:ss.dd
  const h = parseInt(myArr[0]);
  const m = parseInt(myArr[1]);
  const secArr = myArr[2].split('.');
  const s = parseInt(secArr[0]);
  const d = parseInt(secArr[1]);

  return( h*360 + m*60 + s + (0.1*d) );

}

function assToCueArr(assText)
{
 var cueArr=[]; // {start, end, text}
 const lineArr = assText.split(/\r?\n/);
    for( line of lineArr )
    {
      if( line && line.startsWith('Dialogue:'))
      { 
        // Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
        // Dialogue: 0,0:02:16.41,0:02:18.21,Default,,0,0,0,,Sua Santità Sultan Melikşah!
        const myArr = line.split(',');
        cueArr.push( { start: time_str2secs(myArr[1]), end: time_str2secs(myArr[2]), text: filterText(myArr[9]) } );
      }
    }
  return( cueArr );
}

function filterText(str)
{
  str = str.replace(/{[^}]*}/g,''); // {...}
  str = str.replace(/\\N/g,'\n');  // \N
  return(str);
}


const mypid_sub = setInterval(function() // Polling for window.code_sub url
{
  if( window.code_sub && window.code_sub.includes('file2sub') )   {
    // file2sub("https://cdn-s5.cfglobalcdn.com/flv/api/files/srt/2021/03/24/1616595627fcjti-82-tIMf.ass","it","Italian", 'showing', undefined, false);
    const lineArr = window.code_sub.split('\n');
    var suburl = '';
    for(line of lineArr)
    {
       if( line.includes('file2sub') )
       {
           console.log('FOUND  = ' + line );
           suburl = line.replace(/.*file2sub\("([^"]*)".*/, '$1');
           console.log('suburl  = ' + suburl );
           fetchConvert(suburl); 
       }
    }
   clearInterval(mypid_sub);
  }
}, 500); // every 1 sec