您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Скачать фото/аудио/видео-файлы с соц. сети ВКонтакте.
当前为
// ==UserScript== // @name VKDownloadMedia // @namespace https://github.com/KJ86/VKDownloadMedia // @version 5.0 // @date 2016-08-28 // @author KJ86 // @description Скачать фото/аудио/видео-файлы с соц. сети ВКонтакте. // @homepage https://github.com/KJ86/VKDownloadMedia // @include *vk* // @run-at document-end // @grant none // ==/UserScript== (function () { 'use strict'; // ifarme handler if (window.self !== window.top) { var regexp = /vkdm=(.*)/i; var param = regexp.exec(location.hash); if (param !== null) { param = JSON.parse(decodeURIComponent(param[1])); if (typeof param.fileName !== 'undefined') { // Download file var fileExtension = function () { var i, match; var arr = param.url.split('.'); for (i = 0; i < arr.length; i++) { match = arr[i].match(/(.+?)\?/); if (match) { return match[1]; } } }(); var a = document.createElement('a'); a.href = param.url; a.download = param.fileName + '.' + fileExtension; document.body.appendChild(a).click(); window.parent.postMessage('VKDM:' + JSON.stringify(param), '*'); } else if (typeof param.fileSize !== 'undefined') { // Get file size var xhr = new XMLHttpRequest(); xhr.open('HEAD', param.url); xhr.onload = function () { param.fileSize = xhr.getResponseHeader('content-length'); window.parent.postMessage('VKDM:' + JSON.stringify(param), '*'); }; xhr.send(); } } return; } if (location.hostname !== 'vk.com') return; // Add download button (function () { var dwAudioBtn = ce('div', { className: 'audio_act', id: 'vkdm_download_', innerHTML: '<div></div>' }); dwAudioBtn.setAttribute('onmouseover', 'VKDM.audioShowActionTooltip(this)'); dwAudioBtn.setAttribute('onclick', 'VKDM.downloadAudio(this)'); setInterval(function () { // Audio var audioRows = domQuery('.audio_row:not(.candownload)'); if (audioRows.length) { each(audioRows, function (i, audioRow) { var audioActs = audioRow.querySelector('.audio_acts'); var clone = dwAudioBtn.cloneNode(true); clone.id += (Math.random().toString(36).replace('.', '')); clone.setAttribute('data-full-id', audioRow.getAttribute('data-full-id')); audioActs.insertBefore(clone, audioActs.firstElementChild); audioRow.classList.add('candownload'); }); } // Video if (ge('video_player') && !ge('mv_download')) { var videoData = mvcur && mvcur.player && mvcur.player.vars; if (videoData) { var prop, match, items = []; for (prop in videoData) { match = prop.match(/url(\d+)/); if (match) { items.push([prop, match[1], videoData[prop]]); } } if (items.length) { domInsertBefore(ce('div', { className: 'mv_more fl_l', id: 'mv_download', innerHTML: 'Скачать' }), ge('mv_more')); new InlineDropdown('mv_download', { items: items.reverse(), withArrow: true, keepTitle: true, autoShow: true, autoHide: 300, headerLeft: -17, headerTop: -11, sublists: {}, onSelect: function (id, data) { VKDM.downloadVideo(data[2], ge('mv_title').textContent); } }); } } } // Photo var photosAlbumInfo = geByClass1('photos_album_info'); if (photosAlbumInfo && !ge('vkdm_download_album')) { photosAlbumInfo.parentNode.appendChild(cf('<span class="divide">|</span><span class="photos_album_info"><a id="vkdm_download_album" onclick="VKDM.downloadPhotoAlbumsList(); return false;">Скачать альбом</a></span>')); } }, 300); })(); // Add CSS rules document.head.appendChild(ce('style', { type: 'text/css', textContent: '\ .audio_row .audio_acts .audio_act[id^="vkdm_download_"] {display: block}\ .audio_row .audio_acts .audio_act[id^="vkdm_download_"] > div {background-image: url("data:image/gif;base64,R0lGODlhDQANAIABAHKTtgAAACH5BAEAAAEALAAAAAANAA0AAAIYjAOZx+2n1pstgmlxrDabrnCeKD0hhTgFADs=")}' })); // Remove temp iframe window.addEventListener('message', function (e) { if (e.data.indexOf('VKDM:') !== -1) { var data = JSON.parse(e.data.replace('VKDM:', '')); var iframeID = data.iframeID; if (data.fileSize) { var ttElement = document.querySelector('#' + data.ttElementID); ttElement.classList.remove('vkdm_ajax_in_process'); ttElement.setAttribute('data-file-size', data.fileSize); ttElement.setAttribute('data-audio-duration', data.duration); ttElement.tt.shown = false; ttElement.tt.show(); } setTimeout(function () { var iframe = document.querySelector('#' + iframeID); iframe.parentNode.removeChild(iframe); }, 1000); } }, false); // VKDM (Global) window.VKDM = { audioShowActionTooltip: function (btn) { // Get file size if (!btn.hasAttribute('data-file-size')) { if (!btn.classList.contains('vkdm_ajax_in_process')) { ajax.post('al_audio.php', { act: 'reload_audio', ids: btn.getAttribute('data-full-id') }, { onDone: function (items) { createIframeTransport({ url: items[0][2], duration: items[0][5], fileSize: null, ttElementID: btn.id }); } }); btn.classList.add('vkdm_ajax_in_process'); } } showTooltip(btn, { text: function () { var duration = btn.getAttribute('data-audio-duration'); var fileSizeByte = btn.getAttribute('data-file-size'); var fileSizeMByte = 0; var bitrate = 0; if (duration && fileSizeByte) { fileSizeMByte = (fileSizeByte / 1024 / 1024).toFixed(1); bitrate = parseInt(fileSizeByte * 8 / duration / 1000); } return 'Скачать аудиозапись<br>Битрейт: ~' + bitrate + ' кбит/с<br>Размер: ' + fileSizeMByte + ' МБ'; }, black: 1, shift: [7, 5, 0], needLeft: true }); }, downloadAudio: function (btn) { ajax.post('al_audio.php', { act: 'reload_audio', ids: btn.getAttribute('data-full-id') }, { onDone: function (items) { var url = items[0][2]; var fileName = function () { var div = document.createElement('div'); div.innerHTML = items[0][4] + ' – ' + items[0][3]; return div.textContent; }(); createIframeTransport({ url: url, fileName: fileName }); } }); }, downloadVideo: function (url, fileName) { createIframeTransport({ url: url, fileName: fileName }); }, downloadPhotoAlbumsList: function (el) { var items = []; var downloadListBtnWrapID = 'vkdm_' + (Math.random().toString(36).replace('.', '')); var match = location.pathname.match(/album(-?[0-9]+)_([0-9]+)/); var ownerId = match[1]; var albumId = match[2]; var count = 1000; var offset = 0; switch (albumId) { case '0': albumId = 'profile'; break; case '00': albumId = 'wall'; break; case '000': albumId = 'saved'; break; } var onDone = function () { var i, prop, match, nSizes; var srcArr = []; for (i = 0; i < items.length; i++) { nSizes = []; for (prop in items[i]) { match = prop.match(/photo_(\d+)/); if (match) { nSizes.push(match[1]); } } if (nSizes.length) { srcArr.push(items[i]['photo_' + Math.max.apply(null, nSizes)]); } } var downloadListBtnWrap = ge(downloadListBtnWrapID); if (downloadListBtnWrap) { var url = createFile('text/plain;charset=utf-8', srcArr.join('\r\n')); if (url) { var fileName = document.title.replace(/"/g, ''); downloadListBtnWrap.innerHTML = '\ <a href="' + url + '" class="flat_button secondary" download="' + fileName + '.txt">.txt</a> \ <a href="' + url + '" class="flat_button secondary" download="' + fileName + '.urls">.urls</a>'; } else { downloadListBtnWrap.textContent = 'Не удалось создать файл.'; } } }; var getAllItems = function () { getJSONP('https://api.vk.com/method/photos.get?owner_id=' + ownerId + '&album_id=' + albumId + '&count=' + count + '&offset=' + offset + '&v=5.53', function (data) { items = items.concat(data.items); if (items.length === data.count) { onDone(); } else { offset += count; getAllItems(); } }); }; showFastBox({title: 'VKDM - Скачать альбом', dark: 1, hideButtons: 1}, '\ <div style="text-align: center;">\ <div style="color: #777;margin-bottom: 20px">Скачать список всех фотографий с альбома:</div>\ <div id="' + downloadListBtnWrapID + '"><img src="/images/upload.gif" style="margin-top: 10px; margin-bottom: 7px;" /></div>\ </div>\ '); getAllItems(); } }; /*! * Helpers */ function createIframeTransport(params) { var iframeID = 'vkdm_iframe_' + (Math.random().toString(36).replace('.', '')); var data = JSON.stringify(extend({ iframeID: iframeID }, params)); var host = params.url.match(/(^https?:\/\/[^\/]+)/)[1]; var src = host + '/404?#vkdm=' + encodeURIComponent(data); var iframe = ce('iframe', {id: iframeID, src: src, width: '1', height: '1'}, {visibility : 'hidden'}); document.body.appendChild(iframe); } function getJSONP(url, success) { var data = null; var tempFuncName = 'vkdmFunc' + Date.now(); window[tempFuncName] = function (response) { data = response.response; delete window[tempFuncName]; }; document.body.appendChild(ce('script', { src: url + '&callback=' + tempFuncName, onload: function () { success(data); re(this); }, onerror: function () { re(this); } })); } function createFile(type, data) { var url = ''; if (window.URL && window.URL.createObjectURL) { if (createFile.lastBlob) { window.URL.revokeObjectURL(createFile.lastBlob); } url = createFile.lastBlob = window.URL.createObjectURL(new Blob([data], {type: type})); } return url; } })();