This script allows you to watch and download videos on Mediaset Play.
// ==UserScript== // @name Video.mediaset.it native video player and direct links // @name:it Mediaset Play - Link diretti e download video // @namespace http://andrealazzarotto.com // @description This script allows you to watch and download videos on Mediaset Play. // @description:it Ti permette di guardare e scaricare i video da Mediaset Play // @match https://mediasetinfinity.mediaset.it/* // @match https://*.mediasetinfinity.mediaset.it/* // @match https://*.mediasetplay.mediaset.it/* // @match https://www.mediaset.it/* // @version 7.1.3 // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js // @require https://unpkg.com/@ungap/[email protected]/min.js // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @connect mediaset.it // @connect video.mediaset.it // @connect cdnselector.xuniplay.fdnames.com // @connect execute-api.eu-west-1.amazonaws.com // @connect theplatform.eu // @connect akamaized.net // @connect mediaset.net // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // ==/UserScript== /* Greasemonkey 4 wrapper */ if (typeof GM !== "undefined" && !!GM.xmlHttpRequest) { GM_xmlhttpRequest = GM.xmlHttpRequest; } function fetch(params) { return new Promise(function(resolve, reject) { params.onload = resolve; params.onerror = reject; GM_xmlhttpRequest(params); }); } var base_selector = "http://link.theplatform.eu/s/PR1GhC/media/guid/2702976343/[[GUID]]?mbr=true&formats=[[FORMATS]]&format=SMIL&assetTypes=HD,HBBTV,widevine,geoIT%7CgeoNo:HD,HBBTV,geoIT%7CgeoNo:HD,geoIT%7CgeoNo:SD,HBBTV,widevine,geoIT%7CgeoNo:SD,HBBTV,geoIT%7CgeoNo:SD,geoIT%7CgeoNo"; var loc = unsafeWindow.location; var isIframe = loc.href.indexOf("player/") > 0; var isPlay = loc.href.indexOf("mediasetplay.mediaset.it/video/") > 0; function boxStyle(selector, color, textcolor) { $(selector).css({ 'padding': '.5em', 'margin': '1em 4em', 'text-align': 'center', 'background-color': color, 'color': textcolor }); $(selector + ' a').css('color', textcolor); $(selector + ' pre').css({ 'white-space': 'pre-wrap', 'word-break': 'break-all', }); $(selector + ' *').css('font-size', '15px'); $(selector + ' small').css('font-size', '13px'); } function writeLive(stream) { $('#stream-url').remove(); $('<div id="stream-url">').insertAfter($('#playerContainer').parent()); $('#stream-url').append('<p>Flusso della diretta <strong>da aprire con VLC o <code>streamlink</code>:</strong></p>') .append('<pre><code><a href="' + stream + '">' + stream + '</a></code></pre>'); boxStyle('#stream-url', 'rgba(255,255,255,0.5)', 'black'); // kill login timeout unsafeWindow.userNotLogged = function() { return; }; setTimeout(function() { $('.countdown').remove(); }, 1000); } function handleLive(pageURI) { var baseURL = "https://api-ott-prod-fe.mediaset.net/PROD/play/alive/nownext/v1.0?channelId="; if (pageURI.indexOf('/diretta/') < 0) { return; } fetch({ method: 'GET', url: baseURL + pageURI.split('/diretta/')[1].split('_c')[1], headers: { 'Accept': 'application/json' } }).then(function(responseDetails) { var r = responseDetails.responseText; var data = $.parseJSON(r); var instruction = data.response.tuningInstruction; for (var i = 0; i < 5; i++) { var row = instruction['urn:theplatform:tv:location:any'][i]; var public = row.publicUrls[0]; var streaming = row.streamingUrl; if (row.format.indexOf('x-mpegURL') > 0) { return fetch({ method: 'GET', url: public, headers: { 'Accept': 'application/atom+xml,application/xml,text/xml' } }); } } }).then(function(responseDetails) { var src = responseDetails.finalUrl; writeLive(src); }); } function getInformation(vlink) { vlink.url = vlink.url.replace(/vod08\.msf\.cdn/, 'vod05.msf.cdn'); return fetch({ method: 'HEAD', url: vlink.url }).then((response) => { if (response.status == 404) { let r###lt = Object.assign({}, vlink); r###lt.error = true; r###lt.size = 0; return r###lt; } let headers = fromEntries(response.responseHeaders.split("\n").map(element => element.trim().toLowerCase().split(":"))); let size = +headers['content-length']; size = Math.round(size / #### / ####); let r###lt = Object.assign({}, vlink); r###lt.error = false; r###lt.size = size; return r###lt; }); } var range = (start, stop, step) => { var a = [start], b = start; while (b < stop) { a.push(b += step || 1); } return (b > stop) ? a.slice(0,-1) : a; }; var leftPad = (str, padding, length) => { str = `${str}`; while (str.length < length) { str = padding + str; } return str; }; var scrapeQualities = async (url) => { var start = url.match(/[^_]*_[^\/]*/); if (!start) { return []; } start = start[0]; var suffix = start.match(/_.*/)[0].slice(1); var m3u8 = await Promise.all(['ss', 'sd', 'hd'].map(index => { var quality_url = `${start}/hlsrc/${index}_no_mpl.m3u8`; return getInformation({ na: `M3U8 (${index})`, url: quality_url, h: false, quality: index }); })); var r###lts = await Promise.all(['ss', 'sd', 'hd'].map(index => { var quality_url = `${start}/mp4/${index}_no_mpl.mp4`; return getInformation({ na: '.MP4', url: quality_url, h: true, quality: index }); })); return m3u8.concat(r###lts).filter(value => !value.error); }; function getLinks(responseDetails) { var r = responseDetails.responseText; r = r.replace(/msf.ticdn.it/g, 'msf.cdn.mediaset.net'); r = r.replace(/netfarmunica/g, 'net/farmunica'); r = r.replace(/<video/g, '<element'); var doc = $.parseHTML(r); var $xml = $( doc ); var videos = $xml.find("element"); var vlinks = []; console.log($xml[0].innerHTML); var appended = {}; // parse video URLs videos.each(function (i) { var url = $( videos.get(i) ).attr("src"); var type = url.slice(-3); var suffix = (url.match(/\/(ss|sd|hd)_/) || [null, null])[1]; var name = ""; var highlight = false; switch(type) { case "est": name = "ISM"; break; case "3u8": case "pl)": name = suffix ? `M3U8 (${suffix})` : "M3U8"; break; case "mpd": return; case "flv": name = ".FLV"; break; case "f4v": name = ".F4V"; break; case "mp4": name = ".MP4"; highlight = true; break; case "wmv": name = ".WMV"; break; } var ending = url.slice(-20); if (!appended[ending]) { vlinks.push( { na: name, url: url, h: highlight, quality: suffix } ); appended[ending] = true; } }); return vlinks; } function displayURLs(vlinks) { var container = $('#playerContainer'); if (!isIframe && !container.length) { return setTimeout(function() { displayURLs(vlinks); }, 1000); } // Clean up traces $('#video-links, #video-links-actions').remove(); if (isIframe) { $('<div id="video-links">').appendTo('body'); } else { container.parent().after('<div id="video-links">'); } // display video URLs Promise.all(vlinks.map(getInformation)).then(r###lts => { var DRM = false; var scrapeURL = ''; var hasHD = false; r###lts.forEach((o, i) => { scrapeURL = o.url; if (o.quality == 'hd') { hasHD = true; } var s = '<a style="font-weight: ' + (o.h ? 'bold' : 'normal') + '" href="' + o.url + '">' + o.na + (o.size ? ' (' + o.quality + ' ' + o.size + ' MB)' : '') + '</a>'; $(s).appendTo('#video-links'); if (i != r###lts.length-1) { $('<span> | </span>').appendTo('#video-links'); } if (o.url.indexOf('sampleaes') > 0 && o.url.indexOf('.m3u8') > 0) { DRM = true; } }); $('<br><small>I flussi M3U8 devono essere registrati da un programma esterno (es. JDownloader o streamlink)</small>').appendTo('#video-links'); if (DRM || (!hasHD)) { var deepScan = () => { $('#video-links strong').html('Scansione profonda in corso...'); scrapeQualities(scrapeURL).then(r###lts => { $('#video-links').empty(); if (r###lts.length) { r###lts.forEach((o, i) => { var s = '<a style="font-weight: ' + (o.h ? 'bold' : 'normal') + '" href="' + o.url + '">' + o.na + (o.size ? ' (' + o.quality + ' ' + o.size + ' MB)' : '') + '</a>'; $(s).appendTo('#video-links'); if (i != r###lts.length-1) { $('<span> | </span>').appendTo('#video-links'); } }); $('<br><small>I flussi M3U8 devono essere registrati da un programma esterno (es. JDownloader o streamlink)</small>').appendTo('#video-links'); } else { $('#video-links').html('<span>Questo video è protetto da DRM perciò <strong>non può essere scaricato.</strong></span>'); } boxStyle('#video-links', 'rgba(0,0,0,0.5)', 'white'); }); }; deepScan(); } boxStyle('#video-links', 'rgba(0,0,0,0.5)', 'white'); if (!isIframe) { $("#video-links").after("<div id='video-links-actions'></div>"); $("#video-links-actions") .append('<center style="font-size: 75%">' + '<a href="https://lazza.me/DonazioneScript">Clicca qui per fare una donazione</a>' + '</center>') .find('a').css('text-decoration', 'underline'); boxStyle('#video-links-actions', 'rgba(0,0,0,0.35)', 'white'); } if(isIframe) { $('#video-links').css({ 'position': 'absolute', 'bottom': '6em', 'left': '5%', 'right': '5%', 'font-size': '.9em', 'z-index': '99999999' }) .append("<span id='close'>×</span>"); $("#close").css({ 'font-weight': 'bold', 'position': 'absolute', 'top': '1em', 'right': '1em', 'cursor': 'pointer' }).click(function() { $("#video-links").fadeOut(); }); $('#video-links a').attr('target', '_blank'); boxStyle('#video-links', 'white', 'black'); } }); } function get_urls() { var params = new URLSearchParams(location.search.slice(1)); var guid = (loc.href.match(/(FAFU000000([0-9]{4,6})|F[0-9A-F]{14,})/) || [null])[0] || params.get('programGuid') || params.get('id'); if (!!guid && guid.indexOf('FAFU') == 0) { guid = guid.slice(-6); } $("#video-links, #video-links-actions").remove(); if (!!guid) { console.log("GUID: " + guid); var promises = []; ['MPEG4', 'M3U'].forEach((format) => { promises.push( fetch({ method: 'GET', url: base_selector.replace('[[GUID]]', guid).replace('[[FORMATS]]', format), headers: { 'Accept': 'application/atom+xml,application/xml,text/xml' } }).then(getLinks) ); }); Promise.all(promises).then((sets) => { var flat = sets.reduce((acc, val) => acc.concat(val), []); displayURLs(flat); }); } } var old_href = ""; var new_href = ""; function handle_everything() { handleLive(loc.href); get_urls(); } $(document).ready(function(){ setInterval(function() { old_href = new_href; new_href = loc.href; if (new_href != old_href) { handle_everything(); } }, 1000); });