SHARE
TWEET

Untitled

a guest Jan 26th, 2020 106 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 http://cytu.be/r/*
  6. // @include https://cytu.be/r/*
  7. // @include https://agare.moe:8443/r/Agarestream
  8. // @include http://www.cytu.be/r/*
  9. // @include https://www.cytu.be/r/*
  10. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  11. // @grant unsafeWindow
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM.xmlHttpRequest
  14. // @connect docs.google.com
  15. // @run-at document-end
  16. // @version 1.4.0
  17. // ==/UserScript==
  18.  
  19. try {
  20.     function debug(message) {
  21.         if (!unsafeWindow.enableCyTubeGoogleDriveUserscriptDebug) {
  22.             return;
  23.         }
  24.  
  25.         try {
  26.             unsafeWindow.console.log(message);
  27.         } catch (error) {
  28.             unsafeWindow.console.error(error);
  29.         }
  30.     }
  31.  
  32.     var ITAG_QMAP = {
  33.         37: 1080,
  34.         46: 1080,
  35.         22: 720,
  36.         45: 720,
  37.         59: 480,
  38.         44: 480,
  39.         35: 480,
  40.         18: 360,
  41.         43: 360,
  42.         34: 360
  43.     };
  44.  
  45.     var ITAG_CMAP = {
  46.         43: 'video/webm',
  47.         44: 'video/webm',
  48.         45: 'video/webm',
  49.         46: 'video/webm',
  50.         18: 'video/mp4',
  51.         22: 'video/mp4',
  52.         37: 'video/mp4',
  53.         59: 'video/mp4',
  54.         35: 'video/flv',
  55.         34: 'video/flv'
  56.     };
  57.  
  58.     function getVideoInfo(id, cb) {
  59.         var url = 'https://docs.google.com/get_video_info?authuser='
  60.                 + '&docid=' + id
  61.                 + '&sle=true'
  62.                 + '&hl=en';
  63.         debug('Fetching ' + url);
  64.  
  65.         GM.xmlHttpRequest({
  66.             method: 'GET',
  67.             url: url,
  68.             onload: function (res) {
  69.                 try {
  70.                     debug('Got response ' + res.responseText);
  71.                     var data = {};
  72.                     var error;
  73.                     res.responseText.split('&').forEach(function (kv) {
  74.                         var pair = kv.split('=');
  75.                         data[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
  76.                     });
  77.  
  78.                     if (data.status === 'fail') {
  79.                         var error = 'Google Docs request failed: ' +
  80.                                 unescape(data.reason).replace(/\+/g, ' ');
  81.                         return cb(error);
  82.                     }
  83.  
  84.                     if (!data.fmt_stream_map) {
  85.                         var error = 'Google Docs request failed: ' +
  86.                                 'metadata lookup returned no valid links';
  87.                         return cb(error);
  88.                     }
  89.  
  90.                     data.links = {};
  91.                     data.fmt_stream_map.split(',').forEach(function (item) {
  92.                         var pair = item.split('|');
  93.                         data.links[pair[0]] = pair[1];
  94.                     });
  95.                     data.videoMap = mapLinks(data.links);
  96.  
  97.                     cb(null, data);
  98.                 } catch (error) {
  99.                     unsafeWindow.console.error(error);
  100.                 }
  101.             },
  102.  
  103.             onerror: function () {
  104.                 var error = 'Google Docs request failed: ' +
  105.                         'metadata lookup HTTP request failed';
  106.                 error.reason = 'HTTP_ONERROR';
  107.                 return cb(error);
  108.             }
  109.         }).catch(function (error) {
  110.             error.reason = 'GM.xmlHttpRequest error';
  111.             return cb(error);
  112.         });
  113.     }
  114.  
  115.     function mapLinks(links) {
  116.         var videos = {
  117.             1080: [],
  118.             720: [],
  119.             480: [],
  120.             360: []
  121.         };
  122.  
  123.         Object.keys(links).forEach(function (itag) {
  124.             itag = parseInt(itag, 10);
  125.             if (!ITAG_QMAP.hasOwnProperty(itag)) {
  126.                 return;
  127.             }
  128.  
  129.             videos[ITAG_QMAP[itag]].push({
  130.                 itag: itag,
  131.                 contentType: ITAG_CMAP[itag],
  132.                 link: links[itag]
  133.             });
  134.         });
  135.  
  136.         return videos;
  137.     }
  138.  
  139.     /*
  140.      * Greasemonkey 2.0 has this wonderful sandbox that attempts
  141.      * to prevent script developers from shooting themselves in
  142.      * the foot by removing the trigger from the gun, i.e. it's
  143.      * impossible to cross the boundary between the browser JS VM
  144.      * and the privileged sandbox that can run GM_xmlhttpRequest().
  145.      *
  146.      * So in this case, we have to resort to polling a special
  147.      * variable to see if getGoogleDriveMetadata needs to be called
  148.      * and deliver the result into another special variable that is
  149.      * being polled on the browser side.
  150.      */
  151.  
  152.     /*
  153.      * Browser side function -- sets gdUserscript.pollID to the
  154.      * ID of the Drive video to be queried and polls
  155.      * gdUserscript.pollResult for the result.
  156.      */
  157.     function getGoogleDriveMetadata_GM(id, callback) {
  158.         debug('Setting GD poll ID to ' + id);
  159.         unsafeWindow.gdUserscript.pollID = id;
  160.         var tries = 0;
  161.         var i = setInterval(function () {
  162.             if (unsafeWindow.gdUserscript.pollResult) {
  163.                 debug('Got result');
  164.                 clearInterval(i);
  165.                 var result = unsafeWindow.gdUserscript.pollResult;
  166.                 unsafeWindow.gdUserscript.pollResult = null;
  167.                 callback(result.error, result.result);
  168.             } else if (++tries > 100) {
  169.                 // Took longer than 10 seconds, give up
  170.                 clearInterval(i);
  171.             }
  172.         }, 100);
  173.     }
  174.  
  175.     /*
  176.      * Sandbox side function -- polls gdUserscript.pollID for
  177.      * the ID of a Drive video to be queried, looks up the
  178.      * metadata, and stores it in gdUserscript.pollResult
  179.      */
  180.     function setupGDPoll() {
  181.         unsafeWindow.gdUserscript = cloneInto({}, unsafeWindow);
  182.         var pollInterval = setInterval(function () {
  183.             if (unsafeWindow.gdUserscript.pollID) {
  184.                 var id = unsafeWindow.gdUserscript.pollID;
  185.                 unsafeWindow.gdUserscript.pollID = null;
  186.                 debug('Polled and got ' + id);
  187.                 getVideoInfo(id, function (error, data) {
  188.                     unsafeWindow.gdUserscript.pollResult = cloneInto({
  189.                         error: error,
  190.                         result: data
  191.                     }, unsafeWindow);
  192.                 });
  193.             }
  194.         }, 1000);
  195.     }
  196.  
  197.     function isRunningTampermonkey() {
  198.         try {
  199.             return GM_info.scriptHandler === 'Tampermonkey';
  200.         } catch (error) {
  201.             return false;
  202.         }
  203.     }
  204.  
  205.     if (isRunningTampermonkey()) {
  206.         unsafeWindow.getGoogleDriveMetadata = getVideoInfo;
  207.     } else {
  208.         debug('Using non-TM polling workaround');
  209.         unsafeWindow.getGoogleDriveMetadata = exportFunction(
  210.                 getGoogleDriveMetadata_GM, unsafeWindow);
  211.         setupGDPoll();
  212.     }
  213.  
  214.     unsafeWindow.console.log('Initialized userscript Google Drive player');
  215.     unsafeWindow.hasDriveUserscript = true;
  216.     unsafeWindow.driveUserscriptVersion = '1.4';
  217. } catch (error) {
  218.     unsafeWindow.console.error(error);
  219. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top