Greasy Fork

Panopto-Video-DL

Download video from Panopto!

目前为 2021-09-12 提交的版本。查看 最新版本

// ==UserScript==
// @name         Panopto-Video-DL
// @namespace    https://github.com/Panopto-Video-DL
// @description  Download video from Panopto!
// @icon         https://www.panopto.com/wp-content/themes/panopto/library/images/favicons/favicon-96x96.png
// @author       Panopto-Video-DL
// @version      3.0
// @copyright    2021, Panopto-Video-DL
// @license      MIT
// @homepageURL  https://github.com/Panopto-Video-DL
// @match        https://*.panopto.com/Panopto/Pages/Viewer.aspx?*id=*
// @match        https://*.panopto.eu/Panopto/Pages/Viewer.aspx?*id=*
// @grant        GM_setClipboard
// @noframes
// ==/UserScript==

(function(panopto) {
  'use strict';

  const url = new URL(location.href)
  const lesson_id = url.searchParams.get('id');
  if (!lesson_id) {
    alert('Failed to get Lesson ID')
    return; }

  request({
    url: location.origin + '/Panopto/Pages/Viewer/DeliveryInfo.aspx',
    method: 'POST',
    headers: {
      'Accept': 'application/json, text/javascript, */*; q=0.01',
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    data: 'deliveryId=' + lesson_id + '&isEmbed=true&responseType=json',
    success: function(response) {
      const data = JSON.parse(response);
      let stream = undefined;

      try {
        stream = data.Delivery.PodcastStreams[0].StreamUrl;
      } catch (error) {
        console.error(error)
        alert('Error: StreamURL not found');
        return;
      }

      const element = document.createElement('a');
      element.id = 'downloadTabHeader';
      element.classList = 'event-tab-header';
      element.style = 'position:absolute;bottom:40px;padding:5px 10px;text-decoration:none;cursor:pointer;';
      element.innerHTML = '<b>Download</b> <span class="material-icons" style="font-size:15px;vertical-align:middle;">file_download</span>';
      element.addEventListener('click', event => {
        if (localStorage.getItem('popup-viewed') != 'true') {
          const div = document.createElement('div');
          div.id = 'Panopto-Video-DL';
          div.innerHTML += '<style>#Panopto-Video-DL{position:fixed;top:10%;left:50%;width:80%;padding:3em 3em 1em;background-color:#2d3436;transform:translateX(-50%);z-index:999999}#Panopto-Video-DL *:not(small){margin-bottom:10px;color:#fff!important;font-size:18px}#Panopto-Video-DL li,#Panopto-Video-DL ol{margin:0 .5em;padding:0 .5em;list-style:decimal}#Panopto-Video-DL button{margin-top:1em;margin-right:10px;color:#000!important}</style>';
          div.innerHTML += '<h1 style="text-align:center;font-size:26px;">READ ME!</h1> <p>To download the video follow these steps:</p> <ol><li>Download this program from GitHub <a href="https://github.com/Panopto-Video-DL/Panopto-Video-DL/releases" target="_blank">Download</a> (No installation needed) and open it</li> <li>Paste the automatically copied link</li> <li>Wait until the download finishes</li> </ol> <p style="text-align:center;"> <button onclick="this.parentElement.parentElement.remove();">Close</button> <button onclick="localStorage.setItem(\'popup-viewed\', true);this.parentElement.parentElement.remove();">Close and don\'t show again</button> </p>';
          document.querySelector('body').appendChild(div);
        }

        if (typeof GM_setClipboard !== 'undefined') {
          GM_setClipboard(stream, 'text');
          alert('Link Copied')
        } else {
          navigator.clipboard.writeText(stream).then(() => {
            alert('Link Copied')
          }).catch(e => {
            const div = document.createElement('div');
            div.innerHTML += '<style>#Panopto-Video-DL p{font-size:16px}#Panopto-Video-DL input{color:black!important;}</style>';
            div.innerHTML += '<h3>There was an error when automatically copying the download link</h3> <p> Copy it manually: <input type="text" value=""></p>';
            div.querySelector('input').value = stream;
            if (document.querySelector('#Panopto-Video-DL'))
              document.querySelector('#Panopto-Video-DL').append(div)
            else {
              div.id = 'Panopto-Video-DL';
              div.querySelector('style').innerText += '#Panopto-Video-DL{position:fixed;top:10%;left:50%;width:80%;padding:3em 3em 1em;background-color:#2d3436;transform:translateX(-50%);z-index:999999}';
              document.querySelector('body').appendChild(div);
            }
          });
        }
      });
      document.querySelector('#eventTabControl').appendChild(element);
    },
    error: function(response) {
      console.warn(response)
      alert('Failed to get DeliveryInfo of lesson');
    }
  });

  // Functions
  function request(options) {
    const onreadystatechange = function() {
      if (this.readyState === 4 && (this.status >= 200 && this.status <= 299))
        options.success(this.responseText);
      else if (this.readyState === 4)
        options.error(this.responseText);
    };
    if (typeof GM_xmlhttpRequest != 'undefined') {
      options.onload = onreadystatechange;
      GM_xmlhttpRequest(options);
    } else {
      const xhttp = new XMLHttpRequest();
      xhttp.open(options.method || 'GET', options.url);
      if (options.headers) {
        for (let key in options.headers)
          xhttp.setRequestHeader(key, options.headers[key])
      }
      xhttp.onreadystatechange = onreadystatechange;
      xhttp.send(options.data);
    }
  }

})(Panopto);