Code Monkey home page Code Monkey logo

bilibiliapidocs's Introduction

燒餅(Siubeng)

  • Communication language: 💬Cantonese, Mandarin, English. Learning Japanese
  • Most used: Golang, TypeScript, Rust, Kotlin
  • Interest: DevOps, Music, Anime & Games, Android

Recent works / 最近工作

For past works see here.

If you like my projects, you can buy me a coffee at afdian.net <3

bilibiliapidocs's People

Contributors

fython avatar qixingchen avatar yinzo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bilibiliapidocs's Issues

bilibili

// ==UserScript==
// @name Bilibili 港澳台
// @namespace http://kghost.info/
// @Version 1.3.6
// @description: Remove area restriction
// @description:zh-CN 解除区域限制 (修正大会员限制,添加国际友人看国内功能)
// @supportURL https://github.com/kghost/bilibili-area-limit
// @author zealot0630
// @include https://.bilibili.com/
// @run-at document-start
// @description Bilibili 港澳台, 解除区域限制 (修正大会员限制,添加国际友人看国内功能)
// @grant GM_notification
// @grant GM_cookie
// @grant GM.setValue
// @grant GM.getValue
// ==/UserScript==

// (function(modules) { // webpackBootstrap
/
/ // The module cache
// var installedModules = {};
/
/
// // The require function
/
/ function webpack_require(moduleId) {
//
/
/ // Check if module is in cache
// if(installedModules[moduleId]) {
/
/ return installedModules[moduleId].exports;
// }
/
/ // Create a new module (and put it into the cache)
// var module = installedModules[moduleId] = {
/
/ i: moduleId,
// l: false,
/
/ exports: {}
// };
/
/
// // Execute the module function
/
/ modules[moduleId].call(module.exports, module, module.exports, webpack_require);
//
/
/ // Flag the module as loaded
// module.l = true;
/
/
// // Return the exports of the module
/
/ return module.exports;
// }
/
/
//
/
/ // expose the modules object (webpack_modules)
// webpack_require.m = modules;
/
/
// // expose the module cache
/
/ webpack_require.c = installedModules;
//
/
/ // define getter function for harmony exports
// webpack_require.d = function(exports, name, getter) {
/
/ if(!webpack_require.o(exports, name)) {
// Object.defineProperty(exports, name, { enumerable: true, get: getter });
/
/ }
// };
/
/
// // define __esModule on exports
/
/ webpack_require.r = function(exports) {
// if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/
/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
// }
/
/ Object.defineProperty(exports, '__esModule', { value: true });
// };
/
/
// // create a fake namespace object
/
/ // mode & 1: value is a module id, require it
// // mode & 2: merge all properties of value into the ns
/
/ // mode & 4: return value when already ns object
// // mode & 8|1: behave like require
/
/ webpack_require.t = function(value, mode) {
// if(mode & 1) value = webpack_require(value);
/
/ if(mode & 8) return value;
// if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/
/ var ns = Object.create(null);
// webpack_require.r(ns);
/
/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
// if(mode & 2 && typeof value != 'string') for(var key in value) webpack_require.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/
/ return ns;
// };
/
/
// // getDefaultExport function for compatibility with non-harmony modules
/
/ webpack_require.n = function(module) {
// var getter = module && module.__esModule ?
/
/ function getDefault() { return module['default']; } :
// function getModuleExports() { return module; };
/
/ webpack_require.d(getter, 'a', getter);
// return getter;
/
/ };
//
/
/ // Object.prototype.hasOwnProperty.call
// webpack_require.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/
/
// // webpack_public_path
/
/ webpack_require.p = "";
//
/
/
// // Load entry module and return exports
/
/ return webpack_require(webpack_require.s = "./src/main.js");
// })
/
************************************************************/
/
/ ({

// "./src/main.js":
/
!
!
!
./src/main.js !
*
*/
/! no exports provided /
/
/ (function(module, webpack_exports, webpack_require) {

"use strict";
webpack_require.r(webpack_exports);
/* harmony import / var url__WEBPACK_IMPORTED_MODULE_0_ = webpack_require(/! ./url */ "./src/url.js");

(function(XMLHttpRequest) {
class ClassHandler {
constructor(proxy) {
this.proxy = proxy;
}

construct(target, args) {
  const obj = new target(...args);
  return new Proxy(obj, new this.proxy(obj));
}

}

const ProxyGetTarget = Symbol('ProxyGetTarget');
const ProxyGetHandler = Symbol('ProxyGetHandler');
class ObjectHandler {
constructor(target) {
this.target = target;
}

get(target, prop, receiver) {
  if (target.hasOwnProperty(prop)) {
    return Reflect.get(target, prop, receiver);
  } else if (prop == ProxyGetTarget) {
    return target;
  } else if (prop == ProxyGetHandler) {
    return this;
  } else {
    const value = target[prop];
    if (typeof value == 'function')
      return new Proxy(value, new FunctionHandler(value));
    return value;
  }
}

set(target, prop, value) {
  return Reflect.set(target, prop, value);
}

}

class FunctionHandlerBase extends ObjectHandler {
apply(target, thisArg, argumentsList) {
const realTarget = thisArg[ProxyGetTarget];
if (!realTarget) throw new Error('illegal invocations');
return this.call(this.target, thisArg, realTarget, argumentsList);
}
}

class FunctionHandler extends FunctionHandlerBase {
call(fn, proxy, target, argumentsList) {
return fn.apply(target, argumentsList);
}
}

class EventTargetHandler extends ObjectHandler {
constructor(target) {
super(target);
this.listeners = {};
}

getListeners(event) {
  if (!this.listeners.hasOwnProperty(event))
    this.listeners[event] = new Map();
  return this.listeners[event];
}

get(target, prop, receiver) {
  if (prop === 'addEventListener') {
    return new Proxy(
      target.addEventListener,
      new this.addEventListener(target.addEventListener)
    );
  } else if (prop === 'removeEventListener') {
    return new Proxy(
      target.removeEventListener,
      new this.removeEventListener(target.removeEventListener)
    );
  } else return super.get(target, prop, receiver);
}

}

EventTargetHandler.prototype.addEventListener = class extends FunctionHandlerBase {
call(fn, proxy, realTarget, argumentsList) {
const event = argumentsList[0];
const listener = argumentsList[1];
const bridge = listener.bind(proxy);
argumentsList[1] = bridge;
proxy[ProxyGetHandler].getListeners(event).set(listener, bridge);
return fn.apply(realTarget, argumentsList);
}
};

EventTargetHandler.prototype.removeEventListener = class extends FunctionHandlerBase {
call(fn, proxy, realTarget, argumentsList) {
const event = argumentsList[0];
const listener = argumentsList[1];
const cache = proxy[ProxyGetHandler].getListeners(event);
if (cache.has(listener)) {
argumentsList[1] = cache.get(listener);
cache.delete(listener);
}
return fn.apply(realTarget, argumentsList);
}
};

class XhrHandler extends EventTargetHandler {
constructor(target) {
super(target);
this.overrideResponse = false;
this.overrideResponseValue = null;
}

get(target, prop, receiver) {
  if (prop === 'open') {
    return new Proxy(target.open, new this.open(target.open));
  } else if (prop === 'send') {
    return new Proxy(target.send, new this.send(target.send));
  } else if (prop === 'response' && this.overrideResponse) {
    console.log('BAL: Return hooked area limit');
    return this.overrideResponseValue;
  } else if (prop === 'responseText' && this.overrideResponse) {
    console.log('BAL: Return hooked area limit');
    return this.overrideResponseValue;
  } else {
    return super.get(target, prop, receiver);
  }
}

}

const showTamperMonkeyUpdate = () => {
GM.getValue('area__limit', 0).then(last => {
if (last > new Date().getTime() - 86400000) return;
if (
confirm(
'Bilibili 港澳台: 无法获取播放文件信息,如果已开通大会员,请升级油猴到BETA版本'
)
) {
window.open(
'https://chrome.google.com/webstore/detail/tampermonkey-beta/gcalenpjmijncebpfijmoaglllgpjagf',
'_blank'
);
} else {
GM.setValue('area__limit', new Date().getTime());
}
});
};

let limited = false;
XhrHandler.prototype.open = class extends FunctionHandlerBase {
call(fn, proxy, realTarget, argumentsList) {
const method = argumentsList[0];
const url = argumentsList[1];

  if (method === 'GET') {
    if (limited && url.match(_url__WEBPACK_IMPORTED_MODULE_0__["url_play"])) {
      for (const [regs, to] of _url__WEBPACK_IMPORTED_MODULE_0__["url_replace_to"]) {
        function any() {
          for (const reg of regs) {
            if (document.title.match(reg)) return true;
          }
          return false;
        }
        if (any()) {
          argumentsList[1] = url.replace(_url__WEBPACK_IMPORTED_MODULE_0__["url_api_replace"], to.api);
          realTarget.hookCookie = true;
          console.log(`BAL: playurl via proxy ${to.api}.`);
          break;
        }
      }
    } else if (
      (function() {
        for (const status of _url__WEBPACK_IMPORTED_MODULE_0__["url_status"]) {
          if (url.match(status)) return true;
        }
      })()
    ) {
      realTarget.addEventListener('readystatechange', () => {
        if (realTarget.readyState === 4 && realTarget.status === 200) {
          const status = JSON.parse(realTarget.response);
          if (status && status.result && status.result.area_limit === 1) {
            status.result.area_limit = 0;
            limited = true;
            console.log('BAL: Hook area limit');
            proxy[ProxyGetHandler].overrideResponse = true;
            proxy[ProxyGetHandler].overrideResponseValue = JSON.stringify(
              status
            );
          }
        }
      });
    }
  }
  return fn.apply(realTarget, argumentsList);
}

};

XhrHandler.prototype.send = class extends FunctionHandlerBase {
call(fn, proxy, realTarget, argumentsList) {
if (realTarget.hookCookie) {
GM_cookie.list(
{ domain: '.bilibili.com', name: 'SESSDATA' },
(cookies, error) => {
if (error) {
console.log('BAL: Error fetch cookie, not login');
realTarget.addEventListener('readystatechange', () => {
if (realTarget.readyState === 4 && realTarget.status === 200) {
const status = JSON.parse(realTarget.response);
if (status.code == -10403) showTamperMonkeyUpdate();
}
});
fn.apply(realTarget, argumentsList);
} else {
console.log(BAL: Get Cookie ${cookies});
realTarget.setRequestHeader('X-Cookie', cookies[0].value);
fn.apply(realTarget, argumentsList);
}
}
);
} else {
fn.apply(realTarget, argumentsList);
}
}
};

unsafeWindow.XMLHttpRequest = new Proxy(
XMLHttpRequest,
new ClassHandler(XhrHandler)
);

(() => {
var info = undefined;
Object.defineProperty(unsafeWindow, 'PGC_USERSTATE', {
configurable: true,
get: () => info,
set: v => {
if (v.area_limit == 1) {
console.log('BAL: modify area_limit = 0');
limited = true;
v.area_limit = 0;
}
info = v;
},
});
})();

window.addEventListener('load', () => {
if (document.querySelector('div.error-body')) {
// try load via proxy
console.log('BAL: Load failed, try use proxy');
const avid = //av(\d*)/gm.exec(window.location.pathname)[1];
for (const [u, loc] of url__WEBPACK_IMPORTED_MODULE_0_["url_replace_to"]) {
const detail = loc.api + 'x/web-interface/view/detail?aid=' + avid;
const xhr = new unsafeWindow.XMLHttpRequest();
xhr.open('GET', detail);
xhr.hookCookie = true;
xhr.onreadystatechange = function() {
if (this.readyState === xhr.DONE && this.status === 200) {
const r = JSON.parse(this.responseText).data.View.redirect_url;
console.log(BAL: Redirected to ${r}.);
window.location = r;
}
};
xhr.send();
}
}
});
})(XMLHttpRequest);

/***/ }),

// "./src/url.js":
/
!
****************!
!
./src/url.js !
*
*************/
/
! exports provided: url_status, url_play, url_api_replace, url_replace_to /
/
/ (function(module, webpack_exports, webpack_require) {

"use strict";
webpack_require.r(webpack_exports);
/* harmony export (binding) / webpack_require.d(webpack_exports, "url_status", function() { return url_status; });
/
harmony export (binding) / webpack_require.d(webpack_exports, "url_play", function() { return url_play; });
/
harmony export (binding) / webpack_require.d(webpack_exports, "url_api_replace", function() { return url_api_replace; });
/
harmony export (binding) / webpack_require.d(webpack_exports, "url_replace_to", function() { return url_replace_to; });
const url_status = [
/^https://bangumi.bilibili.com/view/web_api/season/user/status?.
/,
/^https://api.bilibili.com/pgc/view/web/season/user/status?.*/,
];

const url_play = /^https://api.bilibili.com/pgc/player/web/playurl?.*/;

const url_api_replace = /^https://api.bilibili.com//;

const url_replace_to = [
[
// TW
[/僅.*台/],
{
api: 'https://bilibili-tw-api.kghost.info/',
},
],
[
// HK
[/僅.港/],
{
api: 'https://bilibili-hk-api.kghost.info/',
},
],
[
// SG
[/仅限东南亚/],
{
api: 'https://bilibili-sg-api.kghost.info/',
},
],
[
// CN
[/^((?!僅).)
$/],
{
api: 'https://bilibili-cn-api.kghost.info/',
},
],
];

/***/ })

/******/ });
//# sourceMappingURL=bundle.js.map

JS 版本 get_sign 函数的 key 参数是什么?APP KEY?

fython 你好~

我想做的事情是根据视频地址拿到 interface 地址。

根据

http://www.bilibili.com/video/av4371609/

获取到

http://interface.bilibili.com/playurl?cid=7076936&player=1&ts=1460728450&sign=705c096777c7ed41d5cee161913c35be




思路是先手抓一个,然后去用程序跑,看看地址是否一样。
碰到的问题是根据文档里的代码,没成功,想问问咋回事。如题。

手抓的:
http://www.bilibili.com/video/av4371609/
cid 7076936
http://interface.bilibili.com/playurl?cid=7076936&player=1&ts=1460728450&sign=705c096777c7ed41d5cee161913c35be


### 程序
<script type="text/javascript" src="http://static.hdslb.com/js/md5.js"></script>
<script type="text/javascript">

    function get_sign(params, key)
 {
    var s_keys = [];
    for (var i in params)
    {
        s_keys.push(i);
    }
    s_keys.sort();
    var data = "";
    for (var i = 0; i < s_keys.length; i++)
    {
        // encodeURIComponent 返回的转义数字必须为大写( 如 %2F )
        data+=(data ? "&" : "")+s_keys[i]+"="+encodeURIComponent(params[s_keys[i]]);
    }
    return {
        "sign":hex_md5(data+key),
        "params":data
    };
 }

  p = {
    "cid" : "7076936",
    'player' : '1',
    'ts': '1460728588'
  };
/*
# cid = 7076936
# player = 1
# ts = 1460728588
*/
 a = get_sign(p, '85eb6835b0a1034e');
 console.log(a);  

</script>

然后 console(a) 的结果:
// Object { sign: "3a85837f235a317906016f1f6b86dd37", params: "cid=7076936&player=1&ts=1460728588" }

结果应该是 705c096777c7ed41d5cee161913c35be // 因为相同时间戳的那个手抓结果就是这个
但是程序是 3a85837f235a317906016f1f6b86dd37

APPKEY 85eb6835b0a1034e 来源网上的一篇博客。

非常感谢~

是否应该考虑把cn换成com?

我最近也在看关于bilibili的API,发现有些API地址(CONST.typeid.md)可以直接用.com了
bilibili也不知道什么时候从.cn变成.com
并且.com支持https,需不需要把部分.cn换成.com?

如何获取直播、点播地址?

目前根据URL分析 直播地址

http://live-play.acgvideo.com/live/856/live_14837663_7724658.flv
其中856猜测为服务随机数,14837663为视频mid,但最后7724658部分不清楚是什么加密还是什么

点播地址
http://cn-shcy3-dx.acgvideo.com/vg12/f/9a/3215566hd.mp4?expires=1457420100&ssig=Xr96D4B9sG2ZD2W99rOHng&oi=1961670062&appkey=f3bb208b3d081dc8&or=3026306825&rate=0
ssig是通过什么方式加密的?看22位可能是md5(base64),但参数试了几次不太对,不知道是加密方式搞错了,还是加密用数据不对...

网址无法访问

发现api.bilibili.cn和api.bilibili.com无法访问:访问超时,是这个网站关了还是需要全局代理?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.