Pull to refresh

Скачивать музыку и видео с ВК средствами браузера Chrome, используя свое расширение

Reading time 9 min
Views 22K
Добрый день, уважаемые Хабражители. Сегодня хочу поделиться с Вами кодами на Javascript для возможности перекачивания музыки и видео с ВК своими ручками на свой персональный компьютер. Ведь нетрудно себе представить, как записал клевый клип и музыку, потом закачал их туда, но на твоем компьютере все это добро куда то пропало… Что ж, не беда! Мы выкачаем то, что мы закачали туда обратно. Главное, что нам это наш браузер, да сайт позволяют, осталось пораскинуть мозгами.

Для начала нам надо распарсить аудиофайлы… Итак, возьмемся за класс «area clear_fix» и будем пихать в массив то, что принадлежит к классу «play_new». Сначала присвоим в массиве стили, чтобы отловить положение элементов на странице (в последующем для отображения кнопочек рядышком). Потом получим ссылки из input и имя будущего файла из тега b. Потом нужно будет присваивать новым ссылочкам, которые мы будем создавать атрибут download.

function audio(){
var main_div=document.getElementsByClassName("area clear_fix");
for(var i=0;i<main_div.length;i++){
if(main_div[i].parentNode.firstChild.href){
main_div[i].parentNode.firstChild.style.top=main_div[i].getElementsByClassName('play_new')[0].offsetTop+"px";
continue;
}
var _mp3_=main_div[i].getElementsByTagName("input")[0].value.split(",")[0];
var _b_=main_div[i].getElementsByTagName("b")[0];
var _top_=document.getElementById(main_div[0].parentNode.id.replace('audio','play')).offsetTop+"px";
var _t_=main_div[i].getElementsByClassName('play_new')[0].offsetTop+"px";
 var span=main_div[i].getElementsByTagName('span')[0];
 var ispan=span.innerHTML;
  if(span.children[0]){
   var ispan=span.children[0].innerHTML;
  }
var _a_=document.createElement("a");
//_a_.href=""+_mp3_+"&name="+_b_.children[0].innerHTML+"-"+ispan;
_a_.href = _mp3_.substring(0, _mp3_.indexOf('.mp3') + 4);
_a_.download=trim(_b_.children[0].innerHTML+"-"+ispan)+".mp3";
_a_.title='Скачать '+_b_.children[0].innerHTML+"-"+ispan;
_a_.draggable="true";
_a_.innerHTML='<span style="cursor:copy;padding:6px;width:16px;height:16px;background-color:#5F7D9D;color:#fff;border-radius:2px;"><img src="http://st0.vk.me/images/icons/darr.gif" /></span>';
_a_.style.zIndex="10";
_a_.style.left="30px";
_a_.style.top=_t_;
_a_.style.position="absolute";
main_div[i].parentNode.insertBefore(_a_,main_div[i].parentNode.firstChild);
_b_.style.paddingLeft="27px";
}
}


Тут как бы понятно должно быть, все… ну а чтобы отрезать всякий мусор после расширения файла мы применили:
_a_.href = _mp3_.substring(0, _mp3_.indexOf('.mp3') + 4);

В общем уже можно это запустить таким образом через интервал, конечно же если мы находимся на том самом сайте:

setInterval(function(){
  if(window.location.href.indexOf('vk.com')>1) {
 if(document.getElementsByClassName("area clear_fix").length!=0){
  audio();
  }   }  },1000);


Хорошо. Одна функция готова. Пора поведать и о том как скачать видеофайлы…



И снова крепко хватаемся за класс «video_box_wrap» и если данный элемент не содержит атрибута id с downloadvideo, и если нет IFRAME, который нам может подсунуть какой-нибудь ютуб, рутуб — то разбираем его.

function videovk(){
 if(document.getElementsByClassName("video_box_wrap")[0] && !document.getElementById('downloadvideo') && document.getElementById('video_player').tagName!='IFRAME'){
 var invideo=""; var obj = new Object(); var name=new Array(); var content=new Array();
 var fl=encodeURI(unescape(document.getElementsByClassName("video_box_wrap")[0].innerHTML.split(" ")[8].split('"')[1].replace(/amp;/g,"")));
 var flvars=fl.split("&");
 for(var c=0;c<=flvars.length-1;c++){
  name[c]=flvars[c].split("=")[0];
  content[c]=flvars[c].split("=")[1];
 }
 for(var c2=0;c2<=name.length;c2++){
  obj[name[c2]]=content[c2];
 }
 var countvid=0;
   if(obj.url240){
    countvid+=1;
    var invideo=invideo+vv(obj.url240,'240',countvid,obj.md_title);
   }
   if(obj.url360){
    countvid+=1;
    var invideo=invideo+vv(obj.url360,'360',countvid,obj.md_title);
   }
   if(obj.url480){
    countvid+=1;
    var invideo=invideo+vv(obj.url480,'480',countvid,obj.md_title);
   }
   if(obj.url720){
    countvid+=1;
    var invideo=invideo+vv(obj.url720,'720',countvid,obj.md_title);
   }
 
 if(obj.cache240){
  countvid+=1;
  invideo=invideo+vv(obj.cache240,'240',countvid,obj.md_title);
  }
 if(obj.cache360){
  countvid+=1;
  invideo=invideo+vv(obj.cache360,'360',countvid,obj.md_title);
  }
 if(obj.cache480){
  countvid+=1;
  invideo=invideo+vv(obj.cache480,'480',countvid,obj.md_title);
  }
 if(obj.cache720){
  countvid+=1;
  invideo=invideo+vv(obj.cache720,'720',countvid,obj.md_title);
  }
 var videodownloader=document.createElement("div");  videodownloader.style.height="auto";videodownloader.style.width="auto";  videodownloader.id="downloadvideo";videodownloader.style.paddingBottom="5px";
 videodownloader.innerHTML=invideo;
 document.getElementById("mv_narrow").insertBefore(videodownloader, document.getElementById("mv_narrow").firstChild);
 }
}


… из кода понятно что мы формируем ссылки на варианты видео разного формата и добавляем самостоятельно сформированные ссылочки с id=«downloadvideo» атрибутом download сразу к идентификатору mv_narrow.

А дальше нам нужна функция vv для создания ссылок на страничке. Чтобы распознавались русские буквы нам понадобится функция utf8_decode, а чтобы обрезать пробелы по краям функция trim.

Функция декодирования:
function utf8_decode(utftext) {
 var string = "";
 var i = 0;
 var c = c1 = c2 = 0;
 while ( i < utftext.length ) {
  c = utftext.charCodeAt(i);
  if (c < 128) {
   string += String.fromCharCode(c);
   i++;
  }
  else if((c > 191) && (c < 224)) {
   c2 = utftext.charCodeAt(i+1);
   string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
   i += 2;
  }
  else {
   c2 = utftext.charCodeAt(i+1);
   c3 = utftext.charCodeAt(i+2);
   string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
   i += 3;
  }
 }
 return string;
}


Функция обрезки:
function trim(str)
{
 return str.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
}


Функция оформления ссылок:
function vv(a,b,c,d){
if(c%2!=0){
 var p1="<p>";
 var p2="";
}
if(c%2==0 ){
 var p1="";
 var p2="</p>";
}
return p1+"<a style='color:white;background-color:#2F5879;padding:5px 5px 2px 5px; border:#395A7C;' " +
" draggable='true'  title='Скачать: "+utf8_decode(trim(decodeURIComponent(d)))+"' download='"+utf8_decode(trim(decodeURIComponent(d)))+"."+a.substr(-3)+"' href='"+a+"'>"+b+" ("+a.substr(-3)+")</a> "+p2;
}


Основная часть кода готова, осталось поправить интервал:

setInterval(function(){
  if(window.location.href.indexOf('vk.com')>1) {
 if(document.getElementById('video_player') && document.getElementById("mv_narrow")){
  videovk();
  }
 if(document.getElementsByClassName("area clear_fix").length!=0){
  audio();
  }   }  },1000);


Все. когда код готов, и теперь нам нужен манифест, вот он:

{
 "manifest_version":2,
 "name":"Downloader",
 "version":"1.0",
 "description":"Downloader of mp3 files from vk.com and mail.ru.",
 "permissions": [
  "http://vk.com/*",
  "tabs"
 ],
    "content_scripts": [ {
      "js": [ "main.js" ],
      "matches": [ "http://vk.com/*", "http://*.vk.com/*", "https://vk.com/*", "https://*.vk.com/*" ],
      "run_at": "document_end"
   } ],
 "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "browser_action": {
  "default_title":"Downloader Extension"
  }
}


В content_scripts мы пишем что наш код с функциями будет храниться в файле main.js, который будет подгружаться после загрузки страницы, т. е. «run_at»: «document_end».

Думаю этот код будет многим полезен в качестве обучения/использования. Собственно говоря весь код js будет выглядеть так:

function audio(){
var main_div=document.getElementsByClassName("area clear_fix");
for(var i=0;i<main_div.length;i++){
if(main_div[i].parentNode.firstChild.href){
main_div[i].parentNode.firstChild.style.top=main_div[i].getElementsByClassName('play_new')[0].offsetTop+"px";
continue;
}
var _mp3_=main_div[i].getElementsByTagName("input")[0].value.split(",")[0];
var _b_=main_div[i].getElementsByTagName("b")[0];
var _top_=document.getElementById(main_div[0].parentNode.id.replace('audio','play')).offsetTop+"px";
var _t_=main_div[i].getElementsByClassName('play_new')[0].offsetTop+"px";
 var span=main_div[i].getElementsByTagName('span')[0];
 var ispan=span.innerHTML;
  if(span.children[0]){
   var ispan=span.children[0].innerHTML;
  }
var _a_=document.createElement("a");
//_a_.href=""+_mp3_+"&name="+_b_.children[0].innerHTML+"-"+ispan;
_a_.href = _mp3_.substring(0, _mp3_.indexOf('.mp3') + 4);
_a_.download=trim(_b_.children[0].innerHTML+"-"+ispan)+".mp3";
_a_.title='Скачать '+_b_.children[0].innerHTML+"-"+ispan;
_a_.draggable="true";
_a_.innerHTML='<span style="cursor:copy;padding:6px;width:16px;height:16px;background-color:#5F7D9D;color:#fff;border-radius:2px;"><img src="http://st0.vk.me/images/icons/darr.gif" /></span>';
_a_.style.zIndex="10";
_a_.style.left="30px";
_a_.style.top=_t_;
_a_.style.position="absolute";
main_div[i].parentNode.insertBefore(_a_,main_div[i].parentNode.firstChild);
_b_.style.paddingLeft="27px";
}
}


function videovk(){
 if(document.getElementsByClassName("video_box_wrap")[0] && !document.getElementById('downloadvideo') && document.getElementById('video_player').tagName!='IFRAME'){
 var invideo=""; var obj = new Object(); var name=new Array(); var content=new Array();
 var fl=encodeURI(unescape(document.getElementsByClassName("video_box_wrap")[0].innerHTML.split(" ")[8].split('"')[1].replace(/amp;/g,"")));
 var flvars=fl.split("&");
 for(var c=0;c<=flvars.length-1;c++){
  name[c]=flvars[c].split("=")[0];
  content[c]=flvars[c].split("=")[1];
 }
 for(var c2=0;c2<=name.length;c2++){
  obj[name[c2]]=content[c2];
 }
 var countvid=0;
   if(obj.url240){
    countvid+=1;
    var invideo=invideo+vv(obj.url240,'240',countvid,obj.md_title);
   }
   if(obj.url360){
    countvid+=1;
    var invideo=invideo+vv(obj.url360,'360',countvid,obj.md_title);
   }
   if(obj.url480){
    countvid+=1;
    var invideo=invideo+vv(obj.url480,'480',countvid,obj.md_title);
   }
   if(obj.url720){
    countvid+=1;
    var invideo=invideo+vv(obj.url720,'720',countvid,obj.md_title);
   }
 
 if(obj.cache240){
  countvid+=1;
  invideo=invideo+vv(obj.cache240,'240',countvid,obj.md_title);
  }
 if(obj.cache360){
  countvid+=1;
  invideo=invideo+vv(obj.cache360,'360',countvid,obj.md_title);
  }
 if(obj.cache480){
  countvid+=1;
  invideo=invideo+vv(obj.cache480,'480',countvid,obj.md_title);
  }
 if(obj.cache720){
  countvid+=1;
  invideo=invideo+vv(obj.cache720,'720',countvid,obj.md_title);
  }
 var videodownloader=document.createElement("div");  videodownloader.style.height="auto";videodownloader.style.width="auto";  videodownloader.id="downloadvideo";videodownloader.style.paddingBottom="5px";
 videodownloader.innerHTML=invideo;
 document.getElementById("mv_narrow").insertBefore(videodownloader, document.getElementById("mv_narrow").firstChild);
 }
}


function utf8_decode(utftext) {
 var string = "";
 var i = 0;
 var c = c1 = c2 = 0;
 while ( i < utftext.length ) {
  c = utftext.charCodeAt(i);
  if (c < 128) {
   string += String.fromCharCode(c);
   i++;
  }
  else if((c > 191) && (c < 224)) {
   c2 = utftext.charCodeAt(i+1);
   string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
   i += 2;
  }
  else {
   c2 = utftext.charCodeAt(i+1);
   c3 = utftext.charCodeAt(i+2);
   string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
   i += 3;
  }
 }
 return string;
}


function trim(str)
{
 return str.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
}



function vv(a,b,c,d){
if(c%2!=0){
 var p1="<p>";
 var p2="";
}
if(c%2==0 ){
 var p1="";
 var p2="</p>";
}
return p1+"<a style='color:white;background-color:#2F5879;padding:5px 5px 2px 5px; border:#395A7C;' " +
" draggable='true'  title='Скачать: "+utf8_decode(trim(decodeURIComponent(d)))+"' download='"+utf8_decode(trim(decodeURIComponent(d)))+"."+a.substr(-3)+"' href='"+a+"'>"+b+" ("+a.substr(-3)+")</a> "+p2;
}

setInterval(function(){
  if(window.location.href.indexOf('vk.com')>1) {
 if(document.getElementById('video_player') && document.getElementById("mv_narrow")){
  videovk();
  }
 if(document.getElementsByClassName("area clear_fix").length!=0){
  audio();
  }   }  },1000);


Всем удачи!
Tags:
Hubs:
-4
Comments 9
Comments Comments 9

Articles