- // ==UserScript==
- // @name 阿里云原画播放
- // @version 1.1.0
- // @author GreasyFork
- // @date 2023-02-14
- // @description 在画质选项中加入原画播放选项,使用potplayer播放阿里云盘原画视频(需要安装potplayer插件)
- // @license AGPL-3.0-or-later
- // @match *://www.aliyundrive.com/s/*
- // @match *://www.aliyundrive.com/drive*
- // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
- // @require https://unpkg.com/bn.js@4.11.8/lib/bn.js
- // @require https://unpkg.com/@lionello/secp256k1-js@1.1.0/src/secp256k1.js
- // @connect aliyundrive.com
- // @connect localhost
- // @connect *
- // @run-at document-idle
- // @grant unsafeWindow
- // @grant GM_xmlhttpRequest
- // @grant GM_setClipboard
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_openInTab
- // @grant GM_info
- // @grant GM_registerMenuCommand
- // @grant GM_cookie
- // @icon https://gw.alicdn.com/imgextra/i3/O1CN01aj9rdD1GS0E8io11t_!!6000000000620-73-tps-16-16.ico
- // @namespace https://gf.qytechs.cn/users/1026976
- // ==/UserScript==
-
- (function () {
- 'use strict';
- let g_drive_id = "", g_file_id = "", g_file_name = "", g_share_id = "";
- let privateKey = "", publicKey = "";
- let app_id = "", device_id = "",user_id = "";
- let signature = "";
- let headers={};
- let api_url = {
- "0": "https://api.aliyundrive.com/v2/file/get_share_link_download_url",
- "1": "https://api.aliyundrive.com/v2/file/get_download_url"
- };
-
-
- let main = {
-
- isType(obj) {
- return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
- },
-
- post(url, data, headers, type) {
- if (this.isType(data) === 'object') {
- data = JSON.stringify(data);
- }
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- method: "POST", url, headers, data,
- responseType: type || 'json',
- onload: (res) => {
- type === 'blob' ? resolve(res) : resolve(res.response || res.responseText);
- },
- onerror: (err) => {
- reject(err);
- },
- });
- });
- },
-
- getStorage(key) {
- try {
- return JSON.parse(localStorage.getItem(key));
- } catch (e) {
- return localStorage.getItem(key);
- }
- },
-
- async getRealLink(d, f) {
- let res = await this.post(api_url[1], {
- drive_id: d,
- file_id: f
- }, headers);
- //console.log("getRealLink", d,f,res);
- if (res.url) {
- return res.url;
- }
- return '';
- },
-
- async getPCSLink(f, s){
- try {
- let authorization = `${this.getStorage('token').token_type} ${this.getStorage('token').access_token}`;
- let xShareToken = this.getStorage('shareToken').share_token;
- let res = await this.post(api_url[0], {
- expire_sec: 600,
- file_id: g_file_id,
- share_id: g_share_id
- }, {
- authorization,
- "content-type": "application/json;charset=utf-8",
- "x-share-token": xShareToken
- });
- if (res.download_url) {
- return res.download_url;
- }
- } catch (e) {
- //console.log('提示:请先登录(不可用)网盘!');
- }
- },
-
-
- initDefaultConfig() {
- let value = [{
- name: 'url-scheme',
- value: 'potplayer://'
- },];
-
- value.forEach((v) => {
- GM_getValue(v.name) === undefined && GM_setValue(v.name, v.value);
- });
- },
-
- async initECDSAKey() {
- let privateKeyBuf = window.crypto.getRandomValues(new Uint8Array(32));
- privateKey = Secp256k1.uint256(privateKeyBuf, 16);
- publicKey = Secp256k1.generatePublicKeyFromPrivateKeyData(privateKey);
- publicKey = "04" + publicKey.x + publicKey.y;
- app_id = "5dde4e1bdf9e4966b387ba58f4b3fdc3";
- device_id = this.getStorage('cna');
- user_id = this.getStorage('token').user_id;
- console.log("initECDSAKey",privateKeyBuf);
- let nonce = 0;
- //sign
- let text = `${app_id}:${device_id}:${user_id}:${nonce}`;
- let encoder = new TextEncoder();
- let data = encoder.encode(text);
- let hashBuffer = await crypto.subtle.digest('SHA-256', data);
- //hashBuffer to uint8 array
- hashBuffer = new Uint8Array(hashBuffer);
- console.log("hashBuffer",hashBuffer);
- let sig = Secp256k1.ecsign(privateKey, Secp256k1.uint256(hashBuffer, 16));
- signature = sig.r + sig.s + "01";
- headers = {
- "content-type": "application/json;charset=utf-8",
- "authorization": `${this.getStorage('token').token_type} ${this.getStorage('token').access_token}`,
- "origin": "https://www.aliyundrive.com",
- "referer": "https://www.aliyundrive.com/",
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.41",
- "x-canary": "client=web,app=adrive,version=v3.17.0",
- "x-device-id": device_id,
- "x-signature": signature,
- }
- //create session
- const req = await fetch('https://api.aliyundrive.com/users/v1/users/device/create_session', {
- method: 'POST',
- body: JSON.stringify({ "deviceName": "Edge浏览器", "modelName": "Windows网页版", "pubKey": publicKey }),
- headers: headers
- });
- const res = await req.json();
- console.log("create session",res);
- },
-
- init() {
- main.initDefaultConfig();
- main.initECDSAKey();
- //识别页面类型
- let sharepage=window.location.href.indexOf("s/")>0;
- //劫持XMLHttpRequest
- var send = XMLHttpRequest.prototype.send;
- XMLHttpRequest.prototype.send = function (data) {
- let url = this.openParams ? this.openParams[1] : this.responseURL;
- //console.log("aopsend",data)
- if (url.indexOf("/file/get_video_preview_play_info") > 0) {
- //console.log("inject",data)
- g_drive_id = JSON.parse(data).drive_id;
- g_file_id = JSON.parse(data).file_id;
- g_share_id = JSON.parse(data).share_id;
- if (sharepage) {
- g_file_name = document.getElementsByClassName("header-file-name--CN_fq")[0].textContent;
- }
- else {
- g_file_name = document.getElementsByClassName("text--2KGvI")[0].textContent;
- }
- //console.log("got:", url, g_drive_id, g_file_id, g_file_name);
-
- //循环检测dom创建,添加按钮
- let ins = setInterval(() => {
- let quality = document.getElementsByClassName("drawer-list--JYzyI");
- if (quality.length > 0) {
- if (sharepage) {
- quality[0].innerHTML += `<li class="drawer-item--2cNtQ original-video-play" data-is-current="false">
- <div class="text--AMJbu">原画下载</div>
- </li>`;
- let play_button = document.getElementsByClassName("original-video-play")[0];
- play_button.addEventListener("click", async function () {
- let url = await main.getPCSLink(g_file_id, g_share_id);
- let d = document.createElement("a");
- d.download = g_file_name;
- d.rel = "noopener";
- d.href = url;
- d.dispatchEvent(new MouseEvent("click"));
- });
- }
- else {
- quality[2].innerHTML += `<li class="drawer-item--2cNtQ original-video-play" data-is-current="false">
- <div class="text--AMJbu">原画播放</div>
- </li>`;
- let play_button = document.getElementsByClassName("original-video-play")[0];
- play_button.addEventListener("click", async function () {
- let url = await main.getRealLink(g_drive_id, g_file_id);
- let scheme = GM_getValue('url-scheme');
- url = scheme + url;
- let d = document.createElement("a");
- d.download = g_file_name;
- d.rel = "noopener";
- d.href = url;
- d.dispatchEvent(new MouseEvent("click"));
- });
- }
- clearInterval(ins);
- }
- }, 50);
-
- }
-
- send.apply(this, arguments);
- };
- }
- };
- main.init();
- })();