阿里云原画播放

在画质选项中加入原画播放选项,使用potplayer播放阿里云盘原画视频(需要安装potplayer插件)

目前为 2023-02-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 阿里云原画播放
  3. // @version 1.1.0
  4. // @author GreasyFork
  5. // @date 2023-02-14
  6. // @description 在画质选项中加入原画播放选项,使用potplayer播放阿里云盘原画视频(需要安装potplayer插件)
  7. // @license AGPL-3.0-or-later
  8. // @match *://www.aliyundrive.com/s/*
  9. // @match *://www.aliyundrive.com/drive*
  10. // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
  11. // @require https://unpkg.com/bn.js@4.11.8/lib/bn.js
  12. // @require https://unpkg.com/@lionello/secp256k1-js@1.1.0/src/secp256k1.js
  13. // @connect aliyundrive.com
  14. // @connect localhost
  15. // @connect *
  16. // @run-at document-idle
  17. // @grant unsafeWindow
  18. // @grant GM_xmlhttpRequest
  19. // @grant GM_setClipboard
  20. // @grant GM_setValue
  21. // @grant GM_getValue
  22. // @grant GM_openInTab
  23. // @grant GM_info
  24. // @grant GM_registerMenuCommand
  25. // @grant GM_cookie
  26. // @icon https://gw.alicdn.com/imgextra/i3/O1CN01aj9rdD1GS0E8io11t_!!6000000000620-73-tps-16-16.ico
  27. // @namespace https://gf.qytechs.cn/users/1026976
  28. // ==/UserScript==
  29.  
  30. (function () {
  31. 'use strict';
  32. let g_drive_id = "", g_file_id = "", g_file_name = "", g_share_id = "";
  33. let privateKey = "", publicKey = "";
  34. let app_id = "", device_id = "",user_id = "";
  35. let signature = "";
  36. let headers={};
  37. let api_url = {
  38. "0": "https://api.aliyundrive.com/v2/file/get_share_link_download_url",
  39. "1": "https://api.aliyundrive.com/v2/file/get_download_url"
  40. };
  41.  
  42.  
  43. let main = {
  44.  
  45. isType(obj) {
  46. return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
  47. },
  48.  
  49. post(url, data, headers, type) {
  50. if (this.isType(data) === 'object') {
  51. data = JSON.stringify(data);
  52. }
  53. return new Promise((resolve, reject) => {
  54. GM_xmlhttpRequest({
  55. method: "POST", url, headers, data,
  56. responseType: type || 'json',
  57. onload: (res) => {
  58. type === 'blob' ? resolve(res) : resolve(res.response || res.responseText);
  59. },
  60. onerror: (err) => {
  61. reject(err);
  62. },
  63. });
  64. });
  65. },
  66.  
  67. getStorage(key) {
  68. try {
  69. return JSON.parse(localStorage.getItem(key));
  70. } catch (e) {
  71. return localStorage.getItem(key);
  72. }
  73. },
  74.  
  75. async getRealLink(d, f) {
  76. let res = await this.post(api_url[1], {
  77. drive_id: d,
  78. file_id: f
  79. }, headers);
  80. //console.log("getRealLink", d,f,res);
  81. if (res.url) {
  82. return res.url;
  83. }
  84. return '';
  85. },
  86.  
  87. async getPCSLink(f, s){
  88. try {
  89. let authorization = `${this.getStorage('token').token_type} ${this.getStorage('token').access_token}`;
  90. let xShareToken = this.getStorage('shareToken').share_token;
  91. let res = await this.post(api_url[0], {
  92. expire_sec: 600,
  93. file_id: g_file_id,
  94. share_id: g_share_id
  95. }, {
  96. authorization,
  97. "content-type": "application/json;charset=utf-8",
  98. "x-share-token": xShareToken
  99. });
  100. if (res.download_url) {
  101. return res.download_url;
  102. }
  103. } catch (e) {
  104. //console.log('提示:请先登录(不可用)网盘!');
  105. }
  106. },
  107.  
  108.  
  109. initDefaultConfig() {
  110. let value = [{
  111. name: 'url-scheme',
  112. value: 'potplayer://'
  113. },];
  114.  
  115. value.forEach((v) => {
  116. GM_getValue(v.name) === undefined && GM_setValue(v.name, v.value);
  117. });
  118. },
  119.  
  120. async initECDSAKey() {
  121. let privateKeyBuf = window.crypto.getRandomValues(new Uint8Array(32));
  122. privateKey = Secp256k1.uint256(privateKeyBuf, 16);
  123. publicKey = Secp256k1.generatePublicKeyFromPrivateKeyData(privateKey);
  124. publicKey = "04" + publicKey.x + publicKey.y;
  125. app_id = "5dde4e1bdf9e4966b387ba58f4b3fdc3";
  126. device_id = this.getStorage('cna');
  127. user_id = this.getStorage('token').user_id;
  128. console.log("initECDSAKey",privateKeyBuf);
  129. let nonce = 0;
  130. //sign
  131. let text = `${app_id}:${device_id}:${user_id}:${nonce}`;
  132. let encoder = new TextEncoder();
  133. let data = encoder.encode(text);
  134. let hashBuffer = await crypto.subtle.digest('SHA-256', data);
  135. //hashBuffer to uint8 array
  136. hashBuffer = new Uint8Array(hashBuffer);
  137. console.log("hashBuffer",hashBuffer);
  138. let sig = Secp256k1.ecsign(privateKey, Secp256k1.uint256(hashBuffer, 16));
  139. signature = sig.r + sig.s + "01";
  140. headers = {
  141. "content-type": "application/json;charset=utf-8",
  142. "authorization": `${this.getStorage('token').token_type} ${this.getStorage('token').access_token}`,
  143. "origin": "https://www.aliyundrive.com",
  144. "referer": "https://www.aliyundrive.com/",
  145. "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",
  146. "x-canary": "client=web,app=adrive,version=v3.17.0",
  147. "x-device-id": device_id,
  148. "x-signature": signature,
  149. }
  150. //create session
  151. const req = await fetch('https://api.aliyundrive.com/users/v1/users/device/create_session', {
  152. method: 'POST',
  153. body: JSON.stringify({ "deviceName": "Edge浏览器", "modelName": "Windows网页版", "pubKey": publicKey }),
  154. headers: headers
  155. });
  156. const res = await req.json();
  157. console.log("create session",res);
  158. },
  159.  
  160. init() {
  161. main.initDefaultConfig();
  162. main.initECDSAKey();
  163. //识别页面类型
  164. let sharepage=window.location.href.indexOf("s/")>0;
  165. //劫持XMLHttpRequest
  166. var send = XMLHttpRequest.prototype.send;
  167. XMLHttpRequest.prototype.send = function (data) {
  168. let url = this.openParams ? this.openParams[1] : this.responseURL;
  169. //console.log("aopsend",data)
  170. if (url.indexOf("/file/get_video_preview_play_info") > 0) {
  171. //console.log("inject",data)
  172. g_drive_id = JSON.parse(data).drive_id;
  173. g_file_id = JSON.parse(data).file_id;
  174. g_share_id = JSON.parse(data).share_id;
  175. if (sharepage) {
  176. g_file_name = document.getElementsByClassName("header-file-name--CN_fq")[0].textContent;
  177. }
  178. else {
  179. g_file_name = document.getElementsByClassName("text--2KGvI")[0].textContent;
  180. }
  181. //console.log("got:", url, g_drive_id, g_file_id, g_file_name);
  182.  
  183. //循环检测dom创建,添加按钮
  184. let ins = setInterval(() => {
  185. let quality = document.getElementsByClassName("drawer-list--JYzyI");
  186. if (quality.length > 0) {
  187. if (sharepage) {
  188. quality[0].innerHTML += `<li class="drawer-item--2cNtQ original-video-play" data-is-current="false">
  189. <div class="text--AMJbu">原画下载</div>
  190. </li>`;
  191. let play_button = document.getElementsByClassName("original-video-play")[0];
  192. play_button.addEventListener("click", async function () {
  193. let url = await main.getPCSLink(g_file_id, g_share_id);
  194. let d = document.createElement("a");
  195. d.download = g_file_name;
  196. d.rel = "noopener";
  197. d.href = url;
  198. d.dispatchEvent(new MouseEvent("click"));
  199. });
  200. }
  201. else {
  202. quality[2].innerHTML += `<li class="drawer-item--2cNtQ original-video-play" data-is-current="false">
  203. <div class="text--AMJbu">原画播放</div>
  204. </li>`;
  205. let play_button = document.getElementsByClassName("original-video-play")[0];
  206. play_button.addEventListener("click", async function () {
  207. let url = await main.getRealLink(g_drive_id, g_file_id);
  208. let scheme = GM_getValue('url-scheme');
  209. url = scheme + url;
  210. let d = document.createElement("a");
  211. d.download = g_file_name;
  212. d.rel = "noopener";
  213. d.href = url;
  214. d.dispatchEvent(new MouseEvent("click"));
  215. });
  216. }
  217. clearInterval(ins);
  218. }
  219. }, 50);
  220.  
  221. }
  222.  
  223. send.apply(this, arguments);
  224. };
  225. }
  226. };
  227. main.init();
  228. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址