Local Vk Downloader

Get Vk raw link without external service.

  1. // ==UserScript==
  2. // @name Local Vk Downloader
  3. // @namespace vkDownloadAuto
  4. // @version 4.0.0
  5. // @description Get Vk raw link without external service.
  6. // @match https://m.vk.com/mail*
  7. // ==/UserScript==
  8.  
  9. function timeoutPromise(ms, promise) {
  10. return new Promise((resolve, reject) => {
  11. const timeoutId = setTimeout(() => {
  12. reject({ ok: false, message: "promise timeout", timeout: true });
  13. }, ms);
  14. promise.then(
  15. (res) => {
  16. clearTimeout(timeoutId);
  17. resolve(res);
  18. },
  19. (err) => {
  20. clearTimeout(timeoutId);
  21. reject(err);
  22. }
  23. );
  24. })
  25. }
  26.  
  27. function vkPlainGet(url, additionalParams, callback, httpRequest) {
  28. var params = {};
  29. if (additionalParams && typeof additionalParams == "object") {
  30. for (var p in additionalParams) {
  31. params[p] = additionalParams[p];
  32. }
  33. }
  34. params._ajax = 1;
  35. return ajax.plainpost(
  36. url,
  37. params,
  38. (function (e) {
  39. callback(e);
  40. }),
  41. (function () {
  42. callback(null)
  43. }),
  44. !!httpRequest
  45. );
  46. }
  47.  
  48. function vkGet(url, additionalParams, callback) {
  49. return vkPlainGet(url, additionalParams, function (e) {
  50. if (!e) {
  51. callback(null);
  52. return;
  53. }
  54. callback(parseResponse(e));
  55. });
  56. }
  57.  
  58. function vkTimeoutFetch(url, callback) {
  59. var controller = null;
  60. var signal = null;
  61. if (AbortController) {
  62. controller = new AbortController();
  63. signal = controller.signal;
  64. }
  65. timeoutPromise(2000, fetch(url, {
  66. method: 'POST',
  67. signal: signal,
  68. headers: {
  69. 'Content-Type': 'application/x-www-form-urlencoded'
  70. },
  71. body: "_ajax=1"
  72. })).catch(function (error) {
  73. if (error.timeout) {
  74. if (controller) {
  75. controller.abort();
  76. }
  77. }
  78. return null;
  79. }).then(function (result) {
  80. if (!result || result.redirected || !result.ok) {
  81. return null;
  82. }
  83. return result.text();
  84. }).then(function (text) {
  85. callback(text);
  86. return text;
  87. });
  88. }
  89.  
  90. function parseResponse(response) {
  91. if (typeof response == "string" && response.indexOf("<!DOCTYPE html>") != -1) {
  92. return parseDialogPage(response);
  93. }
  94. return parseJSON(response);
  95. }
  96.  
  97. function parseDialogPage(htmlString) {
  98. var html = parseDocumentToHtml(htmlString);
  99. var itemsContainer = html.querySelector(".items");
  100. var items = itemsContainer.querySelector(".photos_page");
  101. var searchMore = itemsContainer.querySelector(".show_more_wrap");
  102. return {
  103. data: [items.outerHTML, searchMore ? searchMore.outerHTML : ""]
  104. }
  105. }
  106.  
  107. function removeCounters(documentString) {
  108. var countersIdx = documentString.indexOf('_cntrs');
  109. if (countersIdx == -1) {
  110. return documentString;
  111. }
  112. var counters = documentString.substring(countersIdx, documentString.indexOf("</div>", countersIdx));
  113. return documentString.replace(counters, '_cntrs">');
  114. }
  115.  
  116. function removeLinks(documentString) {
  117. var linkIdx = documentString.indexOf("<link");
  118. while (linkIdx != -1) {
  119. var linkEndIdx = documentString.indexOf(">", linkIdx);
  120. documentString = documentString.substring(0, linkIdx) + documentString.substring(linkEndIdx + 1);
  121. linkIdx = documentString.indexOf("<link");
  122. }
  123. return documentString;
  124. }
  125.  
  126. function removeScripts(documentString) {
  127. var scriptIdx = documentString.indexOf("<script");
  128. while (scriptIdx != -1) {
  129. var scriptEndIdx = documentString.indexOf("</script", scriptIdx);
  130. documentString = documentString.substring(0, scriptIdx) + documentString.substring(scriptEndIdx + 9);
  131. scriptIdx = documentString.indexOf("<script");
  132. }
  133. return documentString;
  134. }
  135.  
  136. function removeImages(documentString) {
  137. return documentString.replace(/<img/g, "<div").replace(/<\/img/, "</div");
  138. }
  139.  
  140. function removeDuplicates(array) {
  141. return array.filter(function (v, i) {
  142. return array.indexOf(v) === i;
  143. });
  144. }
  145.  
  146. function parseDocumentToHtml(documentString) {
  147. var htmlElement = document.createElement('html');
  148. if (documentString.indexOf("<body") != -1) {
  149. documentString = documentString.substring(documentString.indexOf("<body"), documentString.indexOf("</body>") + 7);
  150. }
  151. documentString = removeCounters(documentString);
  152. documentString = removeLinks(documentString);
  153. documentString = removeScripts(documentString);
  154. htmlElement.innerHTML = documentString;
  155. return htmlElement;
  156. }
  157.  
  158. function getSearchMoreHref(data) {
  159. if (!data || !data[1]) {
  160. return;
  161. }
  162. var htmlElement = parseDocumentToHtml(data[1]);
  163. if (!htmlElement) {
  164. return;
  165. }
  166. var showMore = htmlElement.querySelector(".show_more");
  167. if (!showMore) {
  168. return;
  169. }
  170. var href = showMore.href;
  171. if (!href) {
  172. return null;
  173. }
  174. return href;
  175. }
  176.  
  177. function getPeer() {
  178. var hash = window.location.search;
  179. var idx = hash.indexOf("peer");
  180. if (idx == -1) {
  181. return null;
  182. }
  183. var end = hash.indexOf("&", idx);
  184. if (end == -1) {
  185. end = hash.length;
  186. }
  187. return hash.substring(idx + 5, end);
  188. }
  189.  
  190. function getMediaUrl(newPeer, section) {
  191. var mediaUrlBase = "/mail?act=show_medias&peer=";
  192. var sectionUrl = "&section=";
  193. return mediaUrlBase + newPeer + sectionUrl + section;
  194. }
  195.  
  196. function recursiveGetVideos(searchMoreLink, peer, data, finishState) {
  197. if (!searchMoreLink) {
  198. finishState.videos = true;
  199. finishSegment(peer, data, "videos", finishState);
  200. return;
  201. }
  202. vkGet(searchMoreLink, null, function (result) {
  203. if (!result || !result.data) {
  204. finishSegment(peer, data, "videos", finishState);
  205. return;
  206. }
  207. getVideosLinks(result.data, function (items) {
  208. data.videos = data.videos.concat(items);
  209. var searchMoreLink = getSearchMoreHref(result.data);
  210. recursiveGetVideos(searchMoreLink, peer, data, finishState);
  211. })
  212. });
  213. }
  214.  
  215. function getVideosLinks(data, callback) {
  216. if (!data[0]) {
  217. callback([]);
  218. return;
  219. }
  220. var htmlElement = parseDocumentToHtml(removeImages(data[0]));
  221. var items = htmlElement.querySelectorAll(".video_item");
  222. if (!items || !items.length) {
  223. callback([]);
  224. return;
  225. }
  226. var videos = [];
  227. var fetchLinksCount = items.length;
  228. var reduceFetched = function () {
  229. --fetchLinksCount;
  230. if (fetchLinksCount == 0) {
  231. callback(videos);
  232. }
  233. }
  234. for (var i = 0; i < items.length; ++i) {
  235. var item = items[i];
  236. var itemData = {};
  237. var previewImg = item.querySelector(".th_img");
  238. if (previewImg && previewImg.attributes.getNamedItem("src")) {
  239. itemData.preview = previewImg.attributes.getNamedItem("src").value;
  240. if (itemData.preview == "/images/video/thumbs/blocked_s.png") {
  241. reduceFetched();
  242. continue;
  243. }
  244. }
  245. var videoLength = item.querySelector(".thumb_label");
  246. if (videoLength) {
  247. itemData.length = videoLength.innerText;
  248. }
  249. var videoTitle = item.querySelector(".vi_title_text");
  250. if (videoTitle) {
  251. itemData.title = videoTitle.innerText;
  252. // if (itemData.title.indexOf("Без названия") == -1 && itemData.title.indexOf("_") == -1) {
  253. // reduceFetched();
  254. // continue;
  255. // }
  256. }
  257. var videoHref = item.querySelector(".video_href");
  258. if (!videoHref) {
  259. reduceFetched();
  260. continue;
  261. }
  262. itemData.href = videoHref.href;
  263. var callbackFunction = (function (itemData, result) {
  264. if (!result) {
  265. reduceFetched();
  266. return;
  267. }
  268. var htmlElement = parseDocumentToHtml(removeImages(result));
  269. var sources = htmlElement.querySelectorAll("source[type='video/mp4']");
  270. if (!sources || !sources.length) {
  271. reduceFetched();
  272. return;
  273. }
  274. itemData.sources = [];
  275. for (var i = 0; i < sources.length; ++i) {
  276. itemData.sources.push(sources[i].src);
  277. }
  278. videos.push(itemData);
  279. reduceFetched();
  280. }).bind(this, itemData);
  281. vkTimeoutFetch(itemData.href, callbackFunction, !0);
  282. }
  283. }
  284.  
  285. function getVideos(peer, data, finishState) {
  286. console.log("GET VIDEOS:", peer);
  287. vkGet(getMediaUrl(peer.id, "video"), null, function (result) {
  288. if (!result || !result.data) {
  289. finishSegment(peer, data, "videos", finishState);
  290. return;
  291. }
  292. getVideosLinks(result.data, function (items) {
  293. data.videos = data.videos.concat(items);
  294. var searchMoreLink = getSearchMoreHref(result.data);
  295. recursiveGetVideos(searchMoreLink, peer, data, finishState);
  296. });
  297. });
  298. }
  299.  
  300. function getPhotosLinks(data, callback) {
  301. if (!data[0]) {
  302. callback([]);
  303. return;
  304. }
  305. var htmlElement = parseDocumentToHtml(removeImages(data[0]));
  306. var items = htmlElement.querySelectorAll("div[data-src_big]");
  307. if (!items || !items.length) {
  308. callback([]);
  309. return;
  310. }
  311. var photos = [];
  312. for (var i = 0; i < items.length; ++i) {
  313. var item = items[i];
  314. var src = item.attributes.getNamedItem("data-src_big");
  315. if (!src) {
  316. continue;
  317. }
  318. src = src.value;
  319. var breakIdx = src.indexOf("|");
  320. if (breakIdx != -1) {
  321. src = src.substring(0, breakIdx);
  322. }
  323. photos.push(src);
  324. }
  325. callback(photos);
  326. }
  327.  
  328. function recursiveGetPhotos(searchMoreLink, peer, data, finishState) {
  329. if (!searchMoreLink) {
  330. finishSegment(peer, data, "photos", finishState);
  331. return;
  332. }
  333. vkGet(searchMoreLink, null, function (result) {
  334. if (!result || !result.data) {
  335. finishSegment(peer, data, "photos", finishState);
  336. return;
  337. }
  338. getPhotosLinks(result.data, function (items) {
  339. data.photos = data.photos.concat(items);
  340. var searchMoreLink = getSearchMoreHref(result.data);
  341. recursiveGetPhotos(searchMoreLink, peer, data, finishState);
  342. })
  343. });
  344. }
  345.  
  346. function getPhotos(peer, data, finishState) {
  347. vkGet(getMediaUrl(peer.id, "photo"), null, function (result) {
  348. if (!result || !result.data) {
  349. finishSegment(peer, data, "photos", finishState);
  350. return;
  351. }
  352. getPhotosLinks(result.data, function (items) {
  353. data.photos = data.photos.concat(items);
  354. var searchMoreLink = getSearchMoreHref(result.data);
  355. recursiveGetPhotos(searchMoreLink, peer, data, finishState);
  356. });
  357. });
  358. }
  359.  
  360. function getDocs(peer, data, finishState) {
  361. finishSegment(peer, data, "docs", finishState)
  362. }
  363.  
  364. function getAllMedia(peer) {
  365. var data = {
  366. videos: [],
  367. photos: [],
  368. docs: []
  369. }
  370. var finishState = {
  371. videos: false,
  372. photos: false,
  373. docs: false
  374. }
  375. getVideos(peer, data, finishState);
  376. getPhotos(peer, data, finishState);
  377. getDocs(peer, data, finishState);
  378. }
  379.  
  380. function getPeersFromData(data) {
  381. if (!data[0] || !data[0].msgs || typeof (data[0].msgs) != "object") {
  382. return [];
  383. }
  384. var peers = [];
  385. for (var id in data[0].msgs) {
  386. var message = data[0].msgs[id];
  387. if (!message || !message.peerId) {
  388. continue;
  389. }
  390. var peerId = parseInt(message.peerId);
  391. if (isNaN(peerId) || peerId <= 0 || peerId >= 2000000000) {
  392. continue;
  393. }
  394. var name = "";
  395. if (data[0].members && data[0].members[peerId] && data[0].members[peerId].name) {
  396. name = data[0].members[peerId].name;
  397. }
  398. peers.push({ id: peerId, name: name });
  399. }
  400. return peers.reverse();
  401. }
  402.  
  403. function recursiveGetPeers(peers, offset, step, callback) {
  404. vkGet("/mail", { offset: offset }, function (result) {
  405. if (!result || !result.data) {
  406. callback(peers);
  407. return;
  408. }
  409. var resultPeers = getPeersFromData(result.data);
  410. peers = peers.concat(resultPeers);
  411. peers = removeDuplicates(peers);
  412. if (typeof result.data[1] == "undefined" || result.data[1] == true) {
  413. callback(peers);
  414. return;
  415. }
  416. recursiveGetPeers(peers, offset + step, step, callback);
  417. });
  418. }
  419.  
  420. function start() {
  421. if (peers != null) {
  422. return;
  423. }
  424. peers = [];
  425. recursiveGetPeers(peers, 0, 20, function (receivedPeers) {
  426. peers = receivedPeers;
  427. getAllMedia(peers[0]);
  428. });
  429. }
  430.  
  431. function finishSegment(peer, data, segment, finishState) {
  432. finishState[segment] = true;
  433. if (finishState.videos && finishState.photos && finishState.docs) {
  434. console.log("FINISH:", peer);
  435. finish(peer, data);
  436. var idx = peers.indexOf(peer);
  437. if (idx != -1 && idx != peers.length - 1) {
  438. getAllMedia(peers[idx + 1]);
  439. }
  440. }
  441. }
  442.  
  443. function finish(peer, data) {
  444. media.push({ peer: peer, data: data });
  445. if (media.length == 5) {
  446. printMedia(0, 4);
  447. } else if (media.length == 10) {
  448. printMedia(5, 9);
  449. } else if (media.length == 20) {
  450. printMedia(10, 19);
  451. } else if (media.length == 30) {
  452. printMedia(20, 29);
  453. } else if (media.length == 50) {
  454. printMedia(30, 49);
  455. } else if (media.length == 100) {
  456. printMedia(50, 99);
  457. } else if (media.length == peers.length) {
  458. printAllMedia();
  459. } else if (media.length % 100 == 0) {
  460. printMedia(media.length - 100, media.length - 1);
  461. }
  462. }
  463.  
  464. function printMedia(startIdx, endIdx) {
  465. var mediaPart = media.slice(startIdx, endIdx);
  466. console.log("");
  467. console.log("***********************************MEDIA(" + startIdx + "-" + endIdx + ")**************************************")
  468. console.log(JSON.stringify(mediaPart));
  469. console.log("************************************FINISH**************************************")
  470. }
  471.  
  472. function printAllMedia() {
  473. console.log("");
  474. console.log("***********************************MEDIA(FULL)**************************************")
  475. console.log(JSON.stringify(media));
  476. console.log("************************************FINISH**************************************")
  477. }
  478.  
  479. var peers = null;
  480. var media = [];
  481. start();

QingJ © 2025

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