- // ==UserScript==
- // @name bilibili下载视频
- // @namespace http://tampermonkey.net/
- // @version 0.2.2
- // @description 获取bilibili视频flv下载地址
- // @author bibi
- // @require http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js
- // @match *://*.bilibili.com/video/*
- // @include https://www.bibibili.com/video/*
- // @grant GM_xmlhttpRequest
- // @grant GM_download
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_notification
- // ==/UserScript==
-
- (function() {
- 'use strict';
- /*
- * 公共变量区
- */
- const scriptVersion = GM_info.script.version.trim(); //本程序的版本
- const scriptIcon = GM_info.script.icon64 || GM_info.script.icon; //本程序的图标
- const scriptName = "bilibilidownload";
- var currentUrl=document.URL;
- var aria2Port=6800;
- //定义数据数组
- //存储cid序列,用于分p记录
- var allcid=[];
- //存储{名字;url;cid}
- var urlArray=new Array();
- //当前p
- var whichP=0;
- //从全局变量中得到sessdata,用于下载.
- var sessdata="";
-
-
- /******************************************获取下载地址 start********************************************************/
- //获取bv号
- function getBV(){
- //页面获取 bv号
- var bvCode=currentUrl.split("?")[0];
- var bvArray=bvCode.split("/");
- //获取当前分p
- if(currentUrl.split("?")[1]){
- var P=currentUrl.split("?")[1];
- if(P.length>2 && P.substr(0, 2) == "p="){
- whichP=parseInt(P.split("=")[1])-1;
- }else{
- whichP=0;
- }
- }else{
- //否则当前p为第一p
- whichP=0;
- }
- return bvArray[4];
- }
-
- //根据bv号获取aid cid
- function getAidAndCid() {
- var bv =getBV();
- var url="https://api.bilibili.com/x/web-interface/view?bvid="+bv;
- return new Promise((resolve,reject)=>{
- $.get(url,
- {},
- function (body){
- var data={};
- data.aid=body.data.aid;
- data.cids=new Array();
- for (let i = 0; i < body.data.pages.length; i++) {
- var mycid={};
- mycid.cid=body.data.pages[i].cid;
- mycid.name=body.data.pages[i].part;
- data.cids[i]=mycid;
- //维护一个cid数组
- allcid[i]=body.data.pages[i].cid;
- }
- //返回数据
- resolve(data);
- }
- )
-
- });
- }
-
- //获取下载url
- function getDownUrl(data) {
- return new Promise((resolve,reject)=>{
- //console.log(data);
- //https://api.bilibili.com/x/player/playurl/
- let myurl="https://api.bilibili.com/x/player/playurl?"
- //根据获取aidcid 获得真实的下载地址。
- const promiseArray=[];
- let i=0;
- data.cids.forEach((key)=>{
- let url=myurl+"avid="+data.aid+"&cid="+key.cid+"&qn=80";
- let promise=promiseGetUrl(url,key);
- promiseArray[i]=promise;
- i++;
- })
- //获取结果数组
- resolve(Promise.all(promiseArray));
- });
- }
-
- //promiseGetUrl 获取多p视频的url
- function promiseGetUrl(url,key) {
- //大于480画质需要验证是否登陆
- //设置cookie
- return new Promise((resolve,reject)=>{
-
- GM_xmlhttpRequest({
- method: 'GET',
- url: url,
- headers: {
- 'Accept':' application / JSON',
- 'Cookie':'SESSDATA='+sessdata+';',
- },
- onload: function(body) {
- var myport={};
- //console.log(body.responseText);
- var mybody=JSON.parse(body.responseText);
- myport.name=key.name;
- myport.cid=key.cid;
- myport.url=mybody.data.durl[0].url;
- resolve(myport);
- }
- });
- });
- }
-
-
- function get(){
- //获取aidcid
- getAidAndCid().then((data)=>{
- return getDownUrl(data)
-
- }).then((data)=>{
- //data为数组
- data.forEach((key)=>{
- //console.log(key.name);
- //console.log(key.url);
- //console.log(key.cid);
- //rpcAria2_2(key,bv);
- });
- //将数据存放至全局数组
- urlArray=data;
- });
- }
- /******************************************设置下载地址end********************************************************/
-
- //设置b站sessdata 因为httponly 无法在cookie中获取
- //不设置只能下载480p视频
- function setSessdata(biliSessdata){
- //保存
- if(biliSessdata!=null&&biliSessdata!=""){
- GM_setValue("bilibilidown-sessdata",biliSessdata);
- GM_notification({text:"设置已保存", title:scriptName, image:scriptIcon});
- }else{
- GM_notification({text:"设置失败,不能为空", title:scriptName, image:scriptIcon});
- }
- //返回
- return
- }
-
- //设置Aria2Part 因为用户可能更改端口号
- //不设置只能下载480p视频
- function setAria2Part(inputbiliSessdata){
- //保存
- if(inputbiliSessdata!=null&&inputbiliSessdata!=""){
- GM_setValue('Aria2Part',inputbiliSessdata);
- GM_notification({text:"aria2c端口已保存", title:scriptName, image:scriptIcon});
- }else{
- GM_notification({text:"设置失败,不能为空", title:scriptName, image:scriptIcon});
- }
- //返回
- return
- }
-
- /******************************************设置界面ui start********************************************************/
- // 设置界面ui
- function setUI(){
-
- var ui2="<div class='bilibili-dropdown' style='position: relative;display: inline-block'>"+
- "<button class='bilibili-dropbtn' style=''background-color: #4CAF50;color: white;padding: 16px;font-size: 16px;border: none;cursor: pointer''>点击下载</button>"+
- "<div class='bilibili-dropdown-content' style='display: none;background-color: #f9f9f9;min-width: 160px;box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);'>"+
- "<li><a id=copyOneUrl href='#'>复制本p</a></li>"+
- "<li><a id=copyAllUrl href='#'>复制全部p</a>"+
- "<li><a id=sendOneUrltoAria2 href='#'>发送本p到aria2</a></li>"+
- "<li><a id=sendAllUrltoAria2 href='#'>发送全部到aria2</a></li>"+
- "<li><input type='text' id='inputSessdata' ></li>"+
- "<li><a id=setSessdata href='#'>设置sessdata</a></li>"+
- "<li><input type='text' id='inputAria2Port'value='6800'></li>"+
- "<li><a id='setAria2Port' href='#'>设置aria2端口号</a></li>"
-
- "</div>"+
- "</div>";
- var uiStr = "<div href='javascript:void(0)' target='_blank' id='bilibilisetUi' style='cursor:pointer;z-index:98;display:block;width:60px;height:30px;line-height:30px;position:fixed;left:0;top:400px;text-align:center;overflow:visible'>"+ui2+"</div>";
- //console.log(uiStr);
- $("body").append(uiStr);
-
- }
- /********************************************设置界面ui end******************************************************/
-
- function getwhencilck( ){
- $("#bilibilisetUi").click(function(){
- get();
- $("#bilibilisetUi").mouseover(function(){
- //显示下拉菜单
- $(".bilibili-dropdown-content").css('display','block');
- });
-
- $("#bilibilisetUi").mouseout(function(){
- $(".bilibili-dropdown-content").css('display','none');
- });
- /************************************************************绑定事件 start***********************************************/
- //绑定事件 点击下载本p视频
- $(".bilibili-dropbtn").click(function(){
- getBV();
- var innerP=0;
- var whichPCid=allcid[whichP];
- for(var i=0;i<urlArray.length;i++){
- if(whichPCid==urlArray[i].cid){
- innerP=i;
- }
- }
-
- function func(){
- GM_notification({text:"下载完成", title:scriptName, image:scriptIcon});
- };
- var details={
- url:urlArray[innerP].url,
- headers:{
- referer:document.URL
- },
- name:urlArray[innerP].name+".flv",
- onload:func
- };
- //调用gm下载
- GM_download(details);
- GM_notification({text:"文件正在下载中,不要关闭本网页", title:scriptName, image:scriptIcon});
- return false;
- })
-
- //复制本p下载Url
- $("#copyOneUrl").click(function(){
- getBV();
- var innerP=0;
- var whichPCid=allcid[whichP];
- for(var i=0;i<urlArray.length;i++){
- if(whichPCid==urlArray[i].cid){
- innerP=i;
- }
- }
- //console.log(urlArray[innerP].cid);
- var tag = document.createElement('input');
- tag.setAttribute('id', 'cp_hgz_input');
- tag.value = urlArray[innerP].url;
- document.getElementsByTagName('body')[0].appendChild(tag);
- document.getElementById('cp_hgz_input').select();
- document.execCommand('copy');
- document.getElementById('cp_hgz_input').remove();
- return false;
- })
-
- //复制全部下载Url
- $("#copyAllUrl").click(function(){
-
- var tag = document.createElement('input');
- tag.setAttribute('id', 'cp_hgz_input');
- for(var i=0;i<=urlArray.length;i++){
- tag.value =tag.value+urlArray[i].url;
- }
- document.getElementsByTagName('body')[0].appendChild(tag);
- document.getElementById('cp_hgz_input').select();
- document.execCommand('copy');
- document.getElementById('cp_hgz_input').remove();
- return false;
- })
- //发送本p到aria2
- $("#sendOneUrltoAria2").click(function(){
- //得到的数组可能和cid不对应
- getBV();
- var innerP=0;
- var whichPCid=allcid[whichP];
- for(var i=0;i<urlArray.length;i++){
- if(whichPCid==urlArray[i].cid){
- innerP=i;
- }
- }
- let json_rpc = {
- id:'',
- jsonrpc:'2.0',
- method:'aria2.addUri',
- //"method":'system.listMethods',
- params:[
- [urlArray[innerP].url],
- {
- out:urlArray[innerP].name+".flv",
- referer:currentUrl,
-
- }
- ]
- }
- let data=JSON.stringify(json_rpc);
- console.log(data);
- //发送到本地aria2
- $.post(
- 'http://localhost:'+aria2Port+'/jsonrpc',
- data,
- function(body){
- console.log(body);
- if(body=="error"){
- GM_notification({text:"发送失败 请检查aria2端口", title:scriptName, image:scriptIcon});
- }else{
- GM_notification({text:"发送成功", title:scriptName, image:scriptIcon});
- }
- }
- );
- return false;
- })
- //发送全部p到aria2
- $("#sendAllUrltoAria2").click(function(){
- for(var i=0;i<=urlArray;i++){
- let json_rpc = {
- id:'',
- jsonrpc:'2.0',
- method:'aria2.addUri',
- //"method":'system.listMethods',
- params:[
- [urlArray[i].url],
- {
- out:urlArray[i].name+".flv",
- referer:currentUrl,
-
- }
- ]
- }
- let data=JSON.stringify(json_rpc);
- //发送到本地aria2
- $.post(
- 'http://localhost:'+aria2Port+'/jsonrpc',
- data,
- function(body){
- console.log(body);
- }
- );
- }
- return false;
- })
-
- //设置sessdata 如果不设置sessiondata 下载的文件最高为480p
- $("#setSessdata").click(function(){
- var data=$("#inputSessdata").val();
- //console.log(data);
- setSessdata(data);
- return false;
- })
-
- //设置aria2端口号
- $("#setAria2Port").click(function(){
- var data=$("#inputAria2Port").val();
- setAria2Part(data);
- return false;
- })
-
- //
- var sess=GM_getValue("bilibilidown-sessdata");
- console.log(sess);
- if(sess!=""&&sess!=null){
- sessdata=sess;
- };
- $("#inputSessdata").val(sessdata);
- /************************************************************绑定事件 end***********************************************/
- $('#bilibilisetUi').unbind("click");
- });
- };
- //get();
- setUI();
- getwhencilck();
- setInterval(function() {
- if(currentUrl==document.URL) {
- //console.log(currentUrl);
- }else{
- currentUrl=document.URL;
- //console.log(currentUrl);
- //取消事件。
- //$("#bilibilisetUi").unbind("mouseover");
- //$(".bilibili-dropbtn").unbind("click");
- //$("#bilibilisetUi").children().unbind();
- //getwhencilck( );
- }
- }, 3000);
- })();