Guest User

Untitled

a guest
Jan 14th, 2021
63
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name Google Drive Video Player for CyTube
  3. // @namespace gdcytube
  4. // @description Play Google Drive videos on CyTube
  5. // @include https://cytu.be/r/*
  6. // @include https://www.cytu.be/r/*
  7. // @include https://beta.synchtube.me/r/*
  8. // @grant unsafeWindow
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM.xmlHttpRequest
  11. // @connect docs.google.com
  12. // @run-at document-end
  13. // @version 1.7.0
  14. // ==/UserScript==
  15.  
  16. try {
  17.     function debug(message) {
  18.         try {
  19.             unsafeWindow.console.log('[Drive]', message);
  20.         } catch (error) {
  21.             unsafeWindow.console.error(error);
  22.         }
  23.     }
  24.  
  25.     function httpRequest(opts) {
  26.         if (typeof GM_xmlhttpRequest === 'undefined') {
  27.             // Assume GM4.0
  28.             debug('Using GM4.0 GM.xmlHttpRequest');
  29.             GM.xmlHttpRequest(opts);
  30.         } else {
  31.             debug('Using old-style GM_xmlhttpRequest');
  32.             GM_xmlhttpRequest(opts);
  33.         }
  34.     }
  35.  
  36.     var ITAG_QMAP = {
  37.         37: 1080,
  38.         46: 1080,
  39.         22: 720,
  40.         45: 720,
  41.         59: 480,
  42.         44: 480,
  43.         35: 480,
  44.         18: 360,
  45.         43: 360,
  46.         34: 360
  47.     };
  48.  
  49.     var ITAG_CMAP = {
  50.         43: 'video/webm',
  51.         44: 'video/webm',
  52.         45: 'video/webm',
  53.         46: 'video/webm',
  54.         18: 'video/mp4',
  55.         22: 'video/mp4',
  56.         37: 'video/mp4',
  57.         59: 'video/mp4',
  58.         35: 'video/flv',
  59.         34: 'video/flv'
  60.     };
  61.  
  62.     function getVideoInfo(id, cb) {
  63.         var url = 'https://docs.google.com/get_video_info?authuser='
  64.                 + '&docid=' + id
  65.                 + '&sle=true'
  66.                 + '&hl=en';
  67.         debug('Fetching ' + url);
  68.  
  69.         httpRequest({
  70.             method: 'GET',
  71.             url: url,
  72.             onload: function (res) {
  73.                 try {
  74.                     debug('Got response ' + res.responseText);
  75.  
  76.                     if (res.status !== 200) {
  77.                         debug('Response status not 200: ' + res.status);
  78.                         return cb(
  79.                             'Google Drive request failed: HTTP ' + res.status
  80.                         );
  81.                     }
  82.  
  83.                     var data = {};
  84.                     var error;
  85.                     // Google Santa sometimes eats login cookies and gets mad if there aren't any.
  86.                     if(/accounts\.google\.com\/ServiceLogin/.test(res.responseText)){
  87.                         error = 'Google Docs request failed: ' +
  88.                                 'This video requires you be logged into a Google account. ' +
  89.                                 'Open your Gmail in another tab and then refresh video.';
  90.                         return cb(error);
  91.                     }
  92.  
  93.                     res.responseText.split('&').forEach(function (kv) {
  94.                         var pair = kv.split('=');
  95.                         data[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
  96.                     });
  97.  
  98.                     if (data.status === 'fail') {
  99.                         error = 'Google Drive request failed: ' +
  100.                                 unescape(data.reason).replace(/\+/g, ' ');
  101.                         return cb(error);
  102.                     }
  103.  
  104.                     if (!data.fmt_stream_map) {
  105.                         error = (
  106.                             'Google has removed the video streams associated' +
  107.                             ' with this item.  It can no longer be played.'
  108.                         );
  109.  
  110.                         return cb(error);
  111.                     }
  112.  
  113.                     data.links = {};
  114.                     data.fmt_stream_map.split(',').forEach(function (item) {
  115.                         var pair = item.split('|');
  116.                         data.links[pair[0]] = pair[1];
  117.                     });
  118.                     data.videoMap = mapLinks(data.links);
  119.  
  120.                     cb(null, data);
  121.                 } catch (error) {
  122.                     unsafeWindow.console.error(error);
  123.                 }
  124.             },
  125.  
  126.             onerror: function () {
  127.                 var error = 'Google Drive request failed: ' +
  128.                             'metadata lookup HTTP request failed';
  129.                 error.reason = 'HTTP_ONERROR';
  130.                 return cb(error);
  131.             }
  132.         });
  133.     }
  134.  
  135.     function mapLinks(links) {
  136.         var videos = {
  137.             1080: [],
  138.             720: [],
  139.             480: [],
  140.             360: []
  141.         };
  142.  
  143.         Object.keys(links).forEach(function (itag) {
  144.             itag = parseInt(itag, 10);
  145.             if (!ITAG_QMAP.hasOwnProperty(itag)) {
  146.                 return;
  147.             }
  148.  
  149.             videos[ITAG_QMAP[itag]].push({
  150.                 itag: itag,
  151.                 contentType: ITAG_CMAP[itag],
  152.                 link: links[itag]
  153.             });
  154.         });
  155.  
  156.         return videos;
  157.     }
  158.  
  159.     /*
  160.      * Greasemonkey 2.0 has this wonderful sandbox that attempts
  161.      * to prevent script developers from shooting themselves in
  162.      * the foot by removing the trigger from the gun, i.e. it's
  163.      * impossible to cross the boundary between the browser JS VM
  164.      * and the privileged sandbox that can run GM_xmlhttpRequest().
  165.      *
  166.      * So in this case, we have to resort to polling a special
  167.      * variable to see if getGoogleDriveMetadata needs to be called
  168.      * and deliver the result into another special variable that is
  169.      * being polled on the browser side.
  170.      */
  171.  
  172.     /*
  173.      * Browser side function -- sets gdUserscript.pollID to the
  174.      * ID of the Drive video to be queried and polls
  175.      * gdUserscript.pollResult for the result.
  176.      */
  177.     function getGoogleDriveMetadata_GM(id, callback) {
  178.         debug('Setting GD poll ID to ' + id);
  179.         unsafeWindow.gdUserscript.pollID = id;
  180.         var tries = 0;
  181.         var i = setInterval(function () {
  182.             if (unsafeWindow.gdUserscript.pollResult) {
  183.                 debug('Got result');
  184.                 clearInterval(i);
  185.                 var result = unsafeWindow.gdUserscript.pollResult;
  186.                 unsafeWindow.gdUserscript.pollResult = null;
  187.                 callback(result.error, result.result);
  188.             } else if (++tries > 100) {
  189.                 // Took longer than 10 seconds, give up
  190.                 clearInterval(i);
  191.             }
  192.         }, 100);
  193.     }
  194.  
  195.     /*
  196.      * Sandbox side function -- polls gdUserscript.pollID for
  197.      * the ID of a Drive video to be queried, looks up the
  198.      * metadata, and stores it in gdUserscript.pollResult
  199.      */
  200.     function setupGDPoll() {
  201.         unsafeWindow.gdUserscript = cloneInto({}, unsafeWindow);
  202.         var pollInterval = setInterval(function () {
  203.             if (unsafeWindow.gdUserscript.pollID) {
  204.                 var id = unsafeWindow.gdUserscript.pollID;
  205.                 unsafeWindow.gdUserscript.pollID = null;
  206.                 debug('Polled and got ' + id);
  207.                 getVideoInfo(id, function (error, data) {
  208.                     unsafeWindow.gdUserscript.pollResult = cloneInto({
  209.                         error: error,
  210.                         result: data
  211.                     }, unsafeWindow);
  212.                 });
  213.             }
  214.         }, 1000);
  215.     }
  216.  
  217.     var TM_COMPATIBLES = [
  218.         'Tampermonkey',
  219.         'Violentmonkey' // https://github.com/calzoneman/sync/issues/713
  220.     ];
  221.  
  222.     function isTampermonkeyCompatible() {
  223.         try {
  224.             return TM_COMPATIBLES.indexOf(GM_info.scriptHandler) >= 0;
  225.         } catch (error) {
  226.             return false;
  227.         }
  228.     }
  229.  
  230.     if (isTampermonkeyCompatible()) {
  231.         unsafeWindow.getGoogleDriveMetadata = getVideoInfo;
  232.     } else {
  233.         debug('Using non-TM polling workaround');
  234.         unsafeWindow.getGoogleDriveMetadata = exportFunction(
  235.                 getGoogleDriveMetadata_GM, unsafeWindow);
  236.         setupGDPoll();
  237.     }
  238.  
  239.     unsafeWindow.console.log('Initialized userscript Google Drive player');
  240.     unsafeWindow.hasDriveUserscript = true;
  241.     // Checked against GS_VERSION from data.js
  242.     unsafeWindow.driveUserscriptVersion = '1.7';
  243. } catch (error) {
  244.     unsafeWindow.console.error(error);
  245. }
  246.  
  247.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×