class music_get{
constructor(){
this.el=document.getElementsByClassName("audio_row");
this.str_param=[];
this.json=[];
this.last_len=this.el.length;
this.make_str(this.el);
this.load_audio_to_json(0,this.str_param[0]);
}
parse(element_){
//функция, возвращающая id аудио, который надо передать в запросе, чтобы получить ссылку.
//let i=JSON.parse(element_.attributes['data-audio'].nodeValue),s1=i[13].split("/");
//return i[1]+"_"+i[0]+"_"+s1[2]+"_"+s1[s1.length-2];
let i = AudioUtils.asObject(JSON.parse(element_.getAttribute('data-audio')));
return i.fullId+"_"+i.actionHash+"_"+i.urlHash;
}
encode_url(t) {
//функция, декодирующая ссылку на аудиозапись
let c = {v:(t)=> { return t.split('').reverse().join('')},r: (t, e) => {t = t.split('');for (let i, o = _ + _, a = t.length; a--; ) ~(i = o.indexOf(t[a])) && (t[a] = o.substr(i - e, 1));return t.join('')},
s: (t,e)=> { let i = t.length;if (i) { let o = function(t, e) {let i = t.length,o = [];if (i) {let a = i;for (e = Math.abs(e); a--; ) e = (i * (a + 1) ^ e + a) % i,o[a] = e }return o}(t, e), a = 0;for (t = t.split(''); ++a < i; ) t[a] = t.splice(o[i - 1 - a], 1, t[a]) [0];t = t.join('')}return t},
i:(t, e)=> {return c.s(t, e ^ vk.id)},x: (t, e)=> {let i = [];return e = e.charCodeAt(0),each(t.split(''), (t, o) => {i.push(String.fromCharCode(o.charCodeAt(0) ^ e))}),i.join('')}
},_ = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0PQRSTUVWXYZO123456789+/=',h=(t)=>{ if (!t || t.length % 4 == 1) return !1;for (var e, i, o = 0, a = 0, s = ''; i = t.charAt(a++); ) ~(i = _.indexOf(i)) && (e = o % 4 ? 64 * e + i : i, o++ % 4) && (s += String.fromCharCode(255 & e >> ( - 2 * o & 6)));return s};
if ((!window.wbopen || !~(window.open + '').indexOf('wbopen')) && ~t.indexOf('audio_api_unavailable')) {
let e = t.split('?extra=')[1].split('#'),i=''===e[1]?'':h(e[1]);
if (e = h(e[0]), 'string' != typeof i || !e) return t;for (var o, a, s = (i = i ? i.split(String.fromCharCode(9)) : []).length; s--; ) {if (o = (a = i[s].split(String.fromCharCode(11))).splice(0, 1, e) [0], !c[o]) return t; e = c[o].apply(null, a)}if (e && 'http' === e.substr(0, 4)) return e}return t
}
end(){
//для каждой аудиозаписи в html код добавляем кнопку
each(this.json,(_,item)=>{
let els = document.querySelectorAll('[data-full-id="'+item.fullId+'"]')[0];
if(els.children[0].children[6].children.length===3)return;
els.children[0].children[6].innerHTML+="<div onclick='new music_download().download(this);' style='float:right;height:40px;width:40px;background:url(/doc472427950_504561254) no-repeat 5px 5px;'></div>"
els.children[0].children[6].children[2].attributes.info=item;
});
}
make_str(mass){
//функция, добавляющая в массив str_param строки с id аудио, которые будут передаваться в запросе.
each(mass,(i,e)=>{
if(Math.floor(i/10)===i/10)
this.str_param.push(this.parse(e));
else
this.str_param[this.str_param.length-1]+=","+this.parse(e);
});
}
load_audio_to_json(i,l){
//посылаем запрос на сервер вк, в котором в ответ приходит массив с аудио,
//каждый элемент которого мы добавляем в массив this.json
ajax.post("/al_audio.php",{act:'reload_audio',al:'1',ids:l},{onDone:(a)=>{
//each - функция, которая есть на сайте vk.com - похожа на array.forEach
each(a,(_,c)=>{
c=AudioUtils.asObject(c);
//ну естественно декодируем ссылку, как же без этого)
c.url = this.encode_url(c.url);
this.json.push(c);
});
//рекурсия
if(this.str_param.length-1===i) this.end();
else this.load_audio_to_json(i+1,this.str_param[i+1]);
}});
}
_update_scroll(){
//функция, вызывающаяся при скролле страницы.
if(this.el.length===this.last_len)return;
let c = this.el.length,offset=c-this.last_len;
this.last_len=c;
let arr = Array.from(this.el).splice(-offset);
this._load_button(arr);
}
_load_button(list){
//функция, которая подгружает новые кнопки.
let leng=this.str_param.length-1;
this.make_str(list);
this.load_audio_to_json(leng,this.str_param[leng]);
}
}
class music_download{
//constructor(){}
download(e){
this.info = e.attributes.info;
//если формат аудио - .mp3, то просто открываем ссылку в новом окне
if(this.info.url.indexOf(".mp3?")!==-1)
window.open(this.info.url);
else
//с недавнего времени вк стало поддерживать формат .m3u8, который является аудиоплейлистом(текстом),
//в котором содержатся ссылки на промежутки аудио .ts, но ссылки без хоста.
//Исправим это следуюшей функцией response:
fetch(this.info.url).then((e)=>e.text().then((e)=>this.response(e)));
}
response(data){
let alls = data.match(/\n.+?\.ts\?/ig), host=this.info.url.split("index.m3u8")[0];
each(alls,(_,e)=>data=data.replace(e,"\n"+host+e.replace('\n','')));
//скачиваем полученный файл
this.download_data(this.info.title.replace(/[-\/\\:*?"<>|]/gim,'')+".m3u8",data);
}
download_data(f_n, t) {
let e = document.createElement('a');
e.setAttribute('href', //'data:text/plain;charset=utf-8,'
'data:text/html;base64,'+ btoa(t));
e.setAttribute('download', f_n);
e.style.display = 'none';
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
}
var mus = new music_get();
//функция скролла
window.onscroll=()=>mus._update_scroll();
В результате получается примерно вот, что: