├── .gitignore ├── .gitattributes ├── bilibili.png ├── metadata.json ├── application ├── img │ ├── icons │ │ ├── icon56x56.png │ │ ├── icon64x64.png │ │ ├── icon112x112.png │ │ └── icon128x128.png │ └── inside_icon │ │ └── play │ │ ├── view.svg │ │ ├── favorite.svg │ │ ├── coin.svg │ │ ├── like.svg │ │ └── danmaku.svg ├── about │ ├── index.js │ ├── index.css │ └── index.html ├── player │ ├── playinfo.js │ ├── index.html │ ├── index.css │ └── index.js ├── dydetail │ ├── index.js │ ├── index.css │ └── index.html ├── manifest.webapp ├── web │ ├── index.js │ ├── index.css │ └── index.html ├── lib │ ├── loading.js │ ├── jquery.cookie.min.js │ ├── common.css │ ├── jquery.untils.js │ ├── md5.min.js │ └── danmaku.min.js ├── contribution │ ├── index.html │ ├── index.css │ └── index.js ├── allive │ ├── index.html │ ├── index.css │ └── index.js ├── dynamic │ ├── index.html │ ├── index.css │ └── index.js ├── attention │ ├── index.html │ ├── index.css │ └── index.js ├── livelist │ ├── index.html │ ├── index.css │ └── index.js ├── setting │ ├── index.css │ ├── index.html │ └── index.js ├── collection │ ├── index.html │ ├── index.css │ └── index.js ├── musicmenu │ ├── index.html │ ├── index.css │ └── index.js ├── music │ ├── index.html │ ├── index.css │ └── index.js ├── bangmi │ ├── index.html │ ├── index.css │ └── index.js ├── bandetail │ ├── index.html │ ├── index.css │ └── index.js ├── index.html ├── songinfo │ ├── index.css │ ├── index.html │ └── index.js ├── live │ ├── index.html │ ├── index.css │ ├── webscoket.js │ └── index.js ├── user │ ├── index.css │ ├── index.html │ └── index.js ├── index.css ├── danmaku.js └── app.js ├── LICENSE ├── .github └── workflows │ └── main.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | user/user.js 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /bilibili.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openGiraffes/bilibili_kaios/HEAD/bilibili.png -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | {"manifestURL":"app://kai.baiyang.bilibili/manifest.webapp","version":1} -------------------------------------------------------------------------------- /application/img/icons/icon56x56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openGiraffes/bilibili_kaios/HEAD/application/img/icons/icon56x56.png -------------------------------------------------------------------------------- /application/img/icons/icon64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openGiraffes/bilibili_kaios/HEAD/application/img/icons/icon64x64.png -------------------------------------------------------------------------------- /application/img/icons/icon112x112.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openGiraffes/bilibili_kaios/HEAD/application/img/icons/icon112x112.png -------------------------------------------------------------------------------- /application/img/icons/icon128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openGiraffes/bilibili_kaios/HEAD/application/img/icons/icon128x128.png -------------------------------------------------------------------------------- /application/about/index.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | document.activeElement.addEventListener("keydown", handleKeydown); 3 | }); 4 | 5 | function handleKeydown(e) { 6 | $.clearEvent(e); 7 | switch (e.key) { 8 | case "Enter": 9 | case "Backspace": 10 | window.location.href = "../index.html"; 11 | break; 12 | } 13 | } -------------------------------------------------------------------------------- /application/player/playinfo.js: -------------------------------------------------------------------------------- 1 | class playinfo { 2 | constructor(aid, item, mode, interaction) { 3 | this.aid = parseInt(aid); 4 | this.cid = item.cid; 5 | this.duration = item.duration; 6 | this.mode = mode; 7 | if (interaction == undefined) 8 | interaction = false; 9 | this.interaction = interaction; 10 | this.title = 'P' + item.page + " " + item.part; 11 | } 12 | } -------------------------------------------------------------------------------- /application/dydetail/index.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | document.activeElement.addEventListener('keydown', handleKeydown); 3 | }); 4 | 5 | function handleKeydown(e) { 6 | $.clearEvent(e); 7 | switch (e.key) { 8 | case 'E': 9 | case 'Backspace': 10 | case 'SoftRight': 11 | //window.location.href = '../dynamic/index.html'; 12 | window.history.back(); 13 | break; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /application/img/inside_icon/play/view.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /application/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "哔哩哔哩", 3 | "description": "哔哩哔哩KaiOS版", 4 | "version": "1.8.8", 5 | "launch_path": "/index.html", 6 | "type": "privileged", 7 | "origin": "app://kai.baiyang.bilibili", 8 | "icons": { 9 | "56": "/img/icons/icon56x56.png", 10 | "64": "/img/icons/icon64x64.png", 11 | "112": "/img/icons/icon112x112.png", 12 | "128": "/img/icons/icon128x128.png" 13 | }, 14 | "developer": { 15 | "name": "白羊座的一只狼/zixing/michael_eddy", 16 | "url": "http://www.bilibili.com/" 17 | }, 18 | "permissions": { 19 | "attention": {}, 20 | "browser": {}, 21 | "mobilenetwork": {}, 22 | "systemXHR": {} 23 | }, 24 | "ime_default_softkey_bar": true, 25 | "theme_color": "#d26585" 26 | } 27 | -------------------------------------------------------------------------------- /application/about/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | #softkeys { 8 | z-index: 100; 9 | position: fixed; 10 | bottom: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 30px; 14 | background: #dadada; 15 | padding: 3px 5px; 16 | } 17 | 18 | #softkeys > * { 19 | display: inline-block; 20 | width: 72px; 21 | padding: 0 5px; 22 | } 23 | 24 | #softkey-left, 25 | #softkey-right { 26 | font-weight: 400; 27 | font-size: 14px; 28 | color: #323232; 29 | } 30 | 31 | #softkey-right { 32 | text-align: right; 33 | } 34 | 35 | #softkey-center { 36 | font-weight: 600; 37 | font-size: 16px; 38 | width: 76px; 39 | color: #323232; 40 | text-align: center; 41 | } 42 | 43 | .content { 44 | font-size: 14px; 45 | padding: 8px; 46 | } 47 | -------------------------------------------------------------------------------- /application/web/index.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | var id = $.getQueryVar('id'); 3 | if (id === false) { 4 | var link = sessionStorage.getItem('link'); 5 | if (link != null && link != '' && typeof link != 'undefined') 6 | $('#web').attr('src', link); 7 | else 8 | alert('打开地址失败!'); 9 | } 10 | else { 11 | var url = 'https://www.bilibili.com/read/mobile?id=' + id; 12 | $('#web').attr('src', url); 13 | } 14 | document.activeElement.addEventListener('keydown', handleKeydown); 15 | }); 16 | function handleKeydown(e) { 17 | $.clearEvent(e); 18 | switch (e.key) { 19 | case 'E': 20 | case 'Backspace': 21 | case 'SoftRight': 22 | window.location.href = '../dynamic/index.html'; 23 | break; 24 | } 25 | } -------------------------------------------------------------------------------- /application/web/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | -------------------------------------------------------------------------------- /application/lib/loading.js: -------------------------------------------------------------------------------- 1 | //是否全局隐藏加载框 2 | $.golbalhideLoading = false; 3 | $.extend({ 4 | showLoading: function () { 5 | if($.golbalhideLoading) 6 | { 7 | return; 8 | } 9 | try { 10 | if ($(".loading").length == 0) { 11 | var html = '
' + 12 | '
'; 13 | $('body').append(html); 14 | } 15 | else { 16 | $(".loading").show(); 17 | } 18 | } 19 | catch (e) { 20 | console.log(e); 21 | } 22 | }, 23 | hideLoading: function () { 24 | if($.golbalhideLoading) 25 | { 26 | return; 27 | } 28 | $(".loading").hide(); 29 | }, 30 | }); -------------------------------------------------------------------------------- /application/img/inside_icon/play/favorite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /application/dydetail/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /application/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-地址 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /application/contribution/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-投稿 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 28 | 29 | -------------------------------------------------------------------------------- /application/allive/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-直播分区 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /application/dydetail/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-音乐 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /application/dynamic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-动态 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /application/attention/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-关注 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /application/livelist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-直播 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /application/setting/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | #softkeys { 8 | z-index: 100; 9 | position: fixed; 10 | bottom: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 30px; 14 | background: #dadada; 15 | padding: 3px 5px; 16 | } 17 | 18 | #softkeys > * { 19 | display: inline-block; 20 | width: 72px; 21 | padding: 0 5px; 22 | } 23 | 24 | #softkey-left, 25 | #softkey-right { 26 | font-weight: 400; 27 | font-size: 14px; 28 | color: #323232; 29 | line-height: 24px; 30 | line-height: 24px; 31 | } 32 | 33 | #softkey-right { 34 | text-align: right; 35 | line-height: 24px; 36 | } 37 | 38 | #softkey-center { 39 | font-weight: 600; 40 | font-size: 16px; 41 | width: 76px; 42 | color: #323232; 43 | text-align: center; 44 | } 45 | 46 | #container > p { 47 | padding: 4px 8px; 48 | text-align: center; 49 | margin: 0 auto; 50 | } 51 | 52 | .item { 53 | width: 100%; 54 | height: 28px; 55 | line-height: 28px; 56 | } 57 | 58 | .item:focus, 59 | .item.select { 60 | background-color: #d26585; 61 | color: white; 62 | } 63 | -------------------------------------------------------------------------------- /application/collection/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-收藏 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 openkaios 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /application/about/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 关于-凯哔哩 15 | 16 | 17 | 18 |
19 |

作者

20 |

openGiraffes Groups

21 |

22 |

注意!

23 |

转载该软件或者资源导致的一切问题由转载者承担!

24 |

25 |

使用声明

26 |

1、本程序为哔哩哔哩动画第三方客户端,所有资源均来自哔哩哔哩动画

27 |

2、本程序仅供学习交流编程技术使用

28 |

3、如果侵犯您的合法权益,请及时联系本人以第一时间删除

29 |
30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /application/musicmenu/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-音乐 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 27 |
28 |
29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /application/img/inside_icon/play/coin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /application/lib/jquery.cookie.min.js: -------------------------------------------------------------------------------- 1 | /*! jquery.cookie v1.4.1 | MIT */ 2 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); -------------------------------------------------------------------------------- /application/music/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-音乐 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | 37 | 38 | -------------------------------------------------------------------------------- /application/bangmi/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-番剧 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | 37 | 38 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Package OmniSD zip nightly 2 | 3 | on: 4 | schedule: 5 | - cron: "0 22 * * *" # scheduled at 06:00 (UTC+8) everyday 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Package application.zip 16 | run: | 17 | ls application 18 | cd application 19 | zip -r application.zip ./* 20 | mv application.zip ../application.zip 21 | cd .. 22 | zip -r bilibili_kaios-omnisd-nightly.zip application.zip metadata.json 23 | mkdir workdir 24 | mv application.zip workdir/application.zip 25 | mv metadata.json workdir/metadata.json 26 | 27 | - name: Build artifact 28 | uses: actions/upload-artifact@v2 29 | with: 30 | name: bilibili_kaios-omnisd-nightly 31 | path: ./workdir/* 32 | 33 | - name: Upload nightly release 34 | uses: svenstaro/upload-release-action@v2 35 | with: 36 | repo_token: ${{ secrets.ACTION_TOKEN }} 37 | file: ./bilibili_kaios-omnisd-nightly.zip 38 | tag: nightly 39 | body: "Nightly build" 40 | file_glob: true 41 | prerelease: true 42 | overwrite: true 43 | -------------------------------------------------------------------------------- /application/img/inside_icon/play/like.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | 20 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /application/musicmenu/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | font-size: 14px; 7 | text-align: left; 8 | } 9 | 10 | /* Soft Keys */ 11 | #softkeys { 12 | z-index: 100; 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | width: 100%; 17 | height: 30px; 18 | background: #dadada; 19 | padding: 3px 5px; 20 | } 21 | 22 | #softkeys > * { 23 | display: inline-block; 24 | width: 72px; 25 | padding: 0 5px; 26 | } 27 | 28 | #softkey-left, 29 | #softkey-right { 30 | font-weight: 400; 31 | font-size: 14px; 32 | color: #323232; 33 | line-height: 24px; 34 | text-align: left; 35 | } 36 | 37 | #softkey-right { 38 | text-align: right; 39 | line-height: 24px; 40 | } 41 | 42 | #softkey-center { 43 | font-weight: 600; 44 | font-size: 16px; 45 | width: 76px; 46 | color: #323232; 47 | text-align: center; 48 | } 49 | 50 | .items { 51 | padding: 6px; 52 | height: calc(100% - 30px); 53 | margin-bottom: 30px; 54 | } 55 | 56 | .menu_info { 57 | display: flex; 58 | justify-content: flex-start; 59 | } 60 | 61 | .menu_info > img { 62 | height: 100%; 63 | margin-top: 8px; 64 | margin-left: 4px; 65 | max-width: 96px; 66 | } 67 | 68 | .menu_info > .menu_desc { 69 | padding: 5px 0; 70 | width: calc(100% - 96px); 71 | } 72 | 73 | .item { 74 | border: 1px solid gray; 75 | padding: 2px 4px; 76 | } 77 | 78 | .item.select { 79 | border: 1px solid #d26585; 80 | } 81 | -------------------------------------------------------------------------------- /application/bandetail/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-番剧 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 24 |
25 |
26 | 27 |

28 |

追番

29 |

播放

30 |

31 |
32 | 35 | 36 | 37 | 38 | 43 | 44 | -------------------------------------------------------------------------------- /application/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 凯哔哩 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 27 |
28 |
29 |
30 | 31 | 36 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /application/songinfo/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | font-size: 14px; 7 | text-align: left; 8 | } 9 | 10 | /* Soft Keys */ 11 | #softkeys { 12 | z-index: 100; 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | width: 100%; 17 | height: 30px; 18 | background: #dadada; 19 | padding: 3px 5px; 20 | } 21 | 22 | #softkeys > * { 23 | display: inline-block; 24 | width: 72px; 25 | padding: 0 5px; 26 | } 27 | 28 | #softkey-left, 29 | #softkey-right { 30 | font-weight: 400; 31 | font-size: 14px; 32 | color: #323232; 33 | line-height: 24px; 34 | text-align: left; 35 | } 36 | 37 | #softkey-right { 38 | text-align: right; 39 | line-height: 24px; 40 | } 41 | 42 | #softkey-center { 43 | font-weight: 600; 44 | font-size: 16px; 45 | width: 76px; 46 | color: #323232; 47 | text-align: center; 48 | } 49 | 50 | .items { 51 | padding: 6px; 52 | height: calc(100% - 30px); 53 | margin-bottom: 30px; 54 | } 55 | 56 | .song_info, 57 | .user_info { 58 | display: flex; 59 | justify-content: flex-start; 60 | } 61 | 62 | .song_info > img { 63 | height: 100%; 64 | max-width: 96px; 65 | } 66 | 67 | .song_info > .song_desc { 68 | padding: 5px 0; 69 | width: calc(100% - 96px); 70 | } 71 | 72 | .user_info > img { 73 | height: 100%; 74 | max-width: 64px; 75 | margin-left: 6px; 76 | } 77 | 78 | .user_info > .user_desc { 79 | padding: 5px 0; 80 | margin-left: 12px; 81 | width: calc(100% - 64px); 82 | } 83 | -------------------------------------------------------------------------------- /application/img/inside_icon/play/danmaku.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /application/livelist/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | #container { 50 | overflow-x: hidden; 51 | overflow-y: auto; 52 | width: 100%; 53 | height: calc(100% - 30px); 54 | margin-bottom: 30px; 55 | } 56 | 57 | .item { 58 | margin-top: 4px; 59 | } 60 | 61 | .item.select { 62 | border: 2px solid #d26585; 63 | } 64 | 65 | .item .header { 66 | background-color: #d26585; 67 | } 68 | 69 | .roomlist { 70 | position: relative; 71 | display: inline-flex; 72 | width: 100%; 73 | height: 80px; 74 | background-color: white; 75 | outline: none; 76 | overflow-x: auto; 77 | margin-top: 4px; 78 | } 79 | 80 | .roomlist .room { 81 | float: left; 82 | margin-left: 4px; 83 | } 84 | 85 | .roomlist .room > p { 86 | font-size: 14px; 87 | } 88 | 89 | .roomlist .room.select { 90 | background-color: #d26585; 91 | color: white; 92 | } 93 | -------------------------------------------------------------------------------- /application/setting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-设置 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

21 | 22 | 27 |

28 |

29 | 30 | 31 |

32 |

33 | 34 | 35 |

36 |
37 | 38 | 39 | 44 | 45 | -------------------------------------------------------------------------------- /application/songinfo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-音乐 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 |
23 |

24 |

收听:

25 |

收藏:

26 |

分享:

27 |
28 |
29 |
30 |
31 |
32 | 33 |
34 |

35 |

发布于

36 |
37 |
38 |
39 | 40 | 41 | 42 | 47 | 48 | -------------------------------------------------------------------------------- /application/attention/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | /* Soft Keys */ 9 | #softkeys { 10 | z-index: 100; 11 | position: fixed; 12 | bottom: 0; 13 | left: 0; 14 | width: 100%; 15 | height: 30px; 16 | background: #dadada; 17 | padding: 3px 5px; 18 | } 19 | 20 | #softkeys>* { 21 | display: inline-block; 22 | width: 72px; 23 | padding: 0 5px; 24 | } 25 | 26 | #softkey-left, 27 | #softkey-right { 28 | font-weight: 400; 29 | font-size: 14px; 30 | color: #323232; 31 | line-height: 24px; 32 | } 33 | 34 | #softkey-right { 35 | text-align: right; 36 | line-height: 24px; 37 | } 38 | 39 | #softkey-center { 40 | font-weight: 600; 41 | font-size: 16px; 42 | width: 76px; 43 | color: #323232; 44 | text-align: center; 45 | } 46 | 47 | #container { 48 | overflow-x: hidden; 49 | overflow-y: auto; 50 | width: 100%; 51 | height: calc(100% - 30px); 52 | margin-bottom: 30px; 53 | } 54 | 55 | .item { 56 | position: relative; 57 | width: 100%; 58 | height: 60px; 59 | background-color: white; 60 | outline: none; 61 | overflow-x: hidden; 62 | } 63 | 64 | .item.select { 65 | background-color: #d26585; 66 | color: white; 67 | } 68 | 69 | .item img { 70 | height: 100%; 71 | float: left; 72 | outline: none; 73 | padding: 6px; 74 | } 75 | 76 | .item .name { 77 | position: absolute; 78 | left: 78px; 79 | top: 3px; 80 | overflow: hidden; 81 | height: 36px; 82 | line-height: 18px; 83 | font-size: 12px; 84 | } 85 | 86 | .item .sign { 87 | position: absolute; 88 | left: 72px; 89 | bottom: 2px; 90 | font-size: 12px; 91 | color: rgb(115, 115, 115); 92 | white-space: nowrap; 93 | } -------------------------------------------------------------------------------- /application/live/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 凯哔哩-直播 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 |
31 | 35 |
36 |
37 |
38 | 这个是标题 39 | 各种数据 40 |
41 |
42 | 43 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /application/allive/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | #container { 50 | overflow-x: hidden; 51 | overflow-y: auto; 52 | width: 100%; 53 | height: calc(100% - 30px); 54 | margin-bottom: 30px; 55 | } 56 | 57 | .item { 58 | position: relative; 59 | width: 100%; 60 | height: 60px; 61 | background-color: white; 62 | outline: none; 63 | margin: 4px; 64 | } 65 | 66 | .item:focus, 67 | .item.select { 68 | background-color: #d26585; 69 | color: white; 70 | } 71 | 72 | .head2 { 73 | width: 100px; 74 | } 75 | 76 | .item img { 77 | height: 100%; 78 | float: left; 79 | outline: none; 80 | } 81 | 82 | .item .title { 83 | position: absolute; 84 | left: 109px; 85 | top: 3px; 86 | overflow: hidden; 87 | height: 36px; 88 | line-height: 18px; 89 | font-size: 12px; 90 | } 91 | 92 | .item .author { 93 | position: absolute; 94 | left: 130px; 95 | bottom: 2px; 96 | font-size: 12px; 97 | color: rgb(115, 115, 115); 98 | white-space: nowrap; 99 | } -------------------------------------------------------------------------------- /application/lib/common.css: -------------------------------------------------------------------------------- 1 | * { 2 | scroll-behavior: smooth; 3 | } 4 | .loading { 5 | width: 100%; 6 | height: 100%; 7 | z-index: 999; 8 | background: rgba(57, 63, 76, 0.5); 9 | position: fixed; 10 | top: 0; 11 | bottom: 0; 12 | left: 0; 13 | right: 0; 14 | } 15 | .loading > .container { 16 | width: 100px; 17 | height: 100px; 18 | position: relative; 19 | margin: 0 auto; 20 | margin-top: 100px; 21 | z-index: 999; 22 | } 23 | .loading > .container > span { 24 | display: inline-block; 25 | width: 16px; 26 | height: 16px; 27 | border-radius: 50%; 28 | background: #007acc; 29 | position: absolute; 30 | animation: load 1.04s ease infinite; 31 | } 32 | @keyframes load { 33 | 0% { 34 | opacity: 1; 35 | } 36 | 100% { 37 | opacity: 0.2; 38 | } 39 | } 40 | .loading > .container > span:nth-child(1) { 41 | left: 0; 42 | top: 50%; 43 | margin-top: -8px; 44 | animation-delay: 0.13s; 45 | } 46 | .loading > .container > span:nth-child(2) { 47 | left: 14px; 48 | top: 14px; 49 | animation-delay: 0.26s; 50 | } 51 | .loading > .container > span:nth-child(3) { 52 | left: 50%; 53 | top: 0; 54 | margin-left: -8px; 55 | animation-delay: 0.39s; 56 | } 57 | .loading > .container > span:nth-child(4) { 58 | top: 14px; 59 | right: 14px; 60 | animation-delay: 0.52s; 61 | } 62 | .loading > .container > span:nth-child(5) { 63 | right: 0; 64 | top: 50%; 65 | margin-top: -8px; 66 | animation-delay: 0.65s; 67 | } 68 | .loading > .container > span:nth-child(6) { 69 | right: 14px; 70 | bottom: 14px; 71 | animation-delay: 0.78s; 72 | } 73 | .loading > .container > span:nth-child(7) { 74 | bottom: 0; 75 | left: 50%; 76 | margin-left: -8px; 77 | animation-delay: 0.91s; 78 | } 79 | .loading > .container > span:nth-child(8) { 80 | bottom: 14px; 81 | left: 14px; 82 | animation-delay: 1.04s; 83 | } 84 | -------------------------------------------------------------------------------- /application/music/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0 auto; 4 | padding: 0; 5 | text-align: center; 6 | } 7 | 8 | #softkeys { 9 | z-index: 100; 10 | position: fixed; 11 | bottom: 0; 12 | left: 0; 13 | width: 100%; 14 | height: 30px; 15 | background: #dadada; 16 | padding: 3px 5px; 17 | } 18 | 19 | #softkeys > * { 20 | display: inline-block; 21 | width: 72px; 22 | padding: 0 5px; 23 | } 24 | 25 | #softkey-left, 26 | #softkey-right { 27 | font-weight: 400; 28 | font-size: 14px; 29 | color: #323232; 30 | line-height: 24px; 31 | text-align: left; 32 | } 33 | 34 | #softkey-right { 35 | text-align: right; 36 | line-height: 24px; 37 | } 38 | 39 | #softkey-center { 40 | font-weight: 600; 41 | font-size: 16px; 42 | width: 76px; 43 | color: #323232; 44 | text-align: center; 45 | } 46 | 47 | .tab { 48 | width: 100%; 49 | height: 30px; 50 | position: fixed; 51 | top: 0px; 52 | background-color: white; 53 | z-index: 2; 54 | } 55 | 56 | .tab li { 57 | float: left; 58 | list-style: none; 59 | margin: 7.5; 60 | font-size: 14px; 61 | position: relative; 62 | top: -3px; 63 | } 64 | 65 | .focus { 66 | border-bottom: 3px solid #d26585; 67 | } 68 | 69 | .items { 70 | width: 100%; 71 | height: calc(100% - 30px); 72 | overflow-x: hidden; 73 | overflow-y: auto; 74 | z-index: 1; 75 | margin-top: 30px; 76 | margin-bottom: 30px; 77 | } 78 | 79 | .item { 80 | display: flex; 81 | justify-content: center; 82 | font-size: 14px; 83 | margin-top: 4px; 84 | } 85 | 86 | .item:focus, 87 | .item.select { 88 | background-color: #d26585; 89 | color: white; 90 | } 91 | 92 | .item > img { 93 | width: 60px; 94 | margin-left: 4px; 95 | } 96 | 97 | .item .info { 98 | padding: 5px 0; 99 | width: calc(100% - 60px); 100 | } 101 | -------------------------------------------------------------------------------- /application/user/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0 auto; 4 | padding: 0; 5 | text-align: center; 6 | } 7 | 8 | .dialog { 9 | display: none; 10 | border: 1px solid #d26585; 11 | z-index: 999; 12 | padding: 16px; 13 | } 14 | 15 | .info { 16 | display: block; 17 | } 18 | 19 | p { 20 | padding: 6px; 21 | margin: 0; 22 | } 23 | 24 | #softkeys { 25 | z-index: 100; 26 | position: fixed; 27 | bottom: 0; 28 | left: 0; 29 | width: 100%; 30 | height: 30px; 31 | background: #dadada; 32 | padding: 3px 5px; 33 | } 34 | 35 | #softkeys > * { 36 | display: inline-block; 37 | width: 72px; 38 | padding: 0 5px; 39 | } 40 | 41 | #softkey-left, 42 | #softkey-right { 43 | font-weight: 400; 44 | font-size: 14px; 45 | color: #323232; 46 | line-height: 24px; 47 | text-align: left; 48 | } 49 | 50 | #softkey-right { 51 | text-align: right; 52 | line-height: 24px; 53 | } 54 | 55 | #softkey-center { 56 | font-weight: 600; 57 | font-size: 16px; 58 | width: 76px; 59 | color: #323232; 60 | text-align: center; 61 | } 62 | 63 | #menu { 64 | display: none; 65 | z-index: 100; 66 | background: rgba(00, 00, 00, 0.5); 67 | position: fixed; 68 | left: 0; 69 | top: 0; 70 | width: 100%; 71 | height: 100%; 72 | } 73 | 74 | #menucontainer { 75 | position: fixed; 76 | bottom: 30px; 77 | left: 0px; 78 | width: 98%; 79 | background: white; 80 | margin: 3px; 81 | list-style: none; 82 | } 83 | 84 | .menuitem { 85 | position: relative; 86 | background-color: white; 87 | width: 100%; 88 | outline: none; 89 | height: 30px; 90 | padding-left: 5px; 91 | line-height: 30px; 92 | } 93 | 94 | .menuitem.select { 95 | background-color: #d26585; 96 | color: white; 97 | } 98 | 99 | .item.select { 100 | background-color: #d26585; 101 | color: white; 102 | } 103 | 104 | p > input { 105 | height: 24px; 106 | line-height: 24px; 107 | } 108 | 109 | #face { 110 | margin-top: 8px; 111 | } 112 | -------------------------------------------------------------------------------- /application/user/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 凯哔哩-用户 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

21 |

22 |

23 |

24 | 25 |

26 |
27 |
28 | 29 |

UID

30 |

用户名 31 |

32 | 33 | 34 |

35 |

36 | 37 | 38 |

39 |

签名

40 |
41 | 50 | 51 | 52 | 53 | 58 | -------------------------------------------------------------------------------- /application/dynamic/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | .items { 50 | width: 100%; 51 | height: calc(100% - 30px); 52 | overflow-x: hidden; 53 | overflow-y: auto; 54 | margin-bottom: 30px; 55 | z-index: 1; 56 | } 57 | 58 | .item { 59 | margin: 2px; 60 | font-size: 14px; 61 | border: 1px solid #d26585; 62 | } 63 | 64 | .item:focus, 65 | .item.select { 66 | border: 1px solid #e1aaba; 67 | background-color: #d26585; 68 | color: white; 69 | } 70 | 71 | .item .desc { 72 | overflow: hidden; 73 | text-overflow: ellipsis; 74 | display: -webkit-box; 75 | -webkit-line-clamp: 2; 76 | -webkit-box-orient: vertical; 77 | max-height: 40px; 78 | } 79 | 80 | .item .user_info { 81 | width: 100%; 82 | } 83 | 84 | .item .video { 85 | display: flex; 86 | padding: 0 5px; 87 | justify-content: flex-start; 88 | } 89 | 90 | .item .video img { 91 | width: 96px; 92 | height: 100%; 93 | } 94 | 95 | .item .video .info { 96 | width: calc(100% - 98px); 97 | margin-left: 4px; 98 | } 99 | 100 | .item .video .info > p { 101 | text-align: left; 102 | } 103 | 104 | .item .grid.row2 { 105 | display: grid; 106 | grid-template-rows: repeat(2, 50%); 107 | grid-template-columns: repeat(2, 50%); 108 | } 109 | 110 | .item .grid.row3 { 111 | display: grid; 112 | grid-template-rows: repeat(3, 33.33%); 113 | grid-template-columns: repeat(3, 33.33%); 114 | } 115 | -------------------------------------------------------------------------------- /application/bangmi/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | /* Tab */ 50 | .tab { 51 | width: 100%; 52 | height: 30px; 53 | position: fixed; 54 | top: 0px; 55 | background-color: white; 56 | z-index: 2; 57 | } 58 | 59 | .tab li { 60 | float: left; 61 | list-style: none; 62 | margin: 7.5; 63 | font-size: 14px; 64 | position: relative; 65 | top: -3px; 66 | } 67 | 68 | /* Item */ 69 | .items { 70 | width: 100%; 71 | height: calc(100% - 30px); 72 | overflow-x: hidden; 73 | overflow-y: auto; 74 | z-index: 1; 75 | margin-top: 30px; 76 | margin-bottom: 30px; 77 | } 78 | 79 | .focus { 80 | border-bottom: 3px solid #d26585; 81 | } 82 | 83 | .item { 84 | position: relative; 85 | width: 100%; 86 | height: 60px; 87 | background-color: white; 88 | outline: none; 89 | padding: 2px; 90 | } 91 | 92 | .item:focus, 93 | .item.select { 94 | background-color: #d26585; 95 | color: white; 96 | } 97 | 98 | .item img { 99 | height: 100%; 100 | float: left; 101 | outline: none; 102 | } 103 | 104 | .item .title { 105 | position: absolute; 106 | left: 109px; 107 | top: 3px; 108 | overflow: hidden; 109 | height: 36px; 110 | line-height: 18px; 111 | font-size: 12px; 112 | } 113 | 114 | .item .author { 115 | position: absolute; 116 | left: 130px; 117 | bottom: 2px; 118 | font-size: 12px; 119 | color: rgb(115, 115, 115); 120 | white-space: nowrap; 121 | } 122 | -------------------------------------------------------------------------------- /application/bandetail/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | #container { 50 | margin-top: 30px; 51 | margin-bottom: 30px; 52 | } 53 | 54 | /* Tab */ 55 | .tab { 56 | width: 100%; 57 | height: 30px; 58 | position: fixed; 59 | top: 0px; 60 | background-color: white; 61 | z-index: 2; 62 | } 63 | 64 | .tab li { 65 | float: left; 66 | list-style: none; 67 | margin: 7.5; 68 | font-size: 14px; 69 | position: relative; 70 | top: -3px; 71 | } 72 | 73 | /* Item */ 74 | .items { 75 | width: 100%; 76 | height: calc(100% - 30px); 77 | overflow-x: hidden; 78 | overflow-y: auto; 79 | z-index: 1; 80 | margin-top: 30px; 81 | margin-bottom: 30px; 82 | } 83 | 84 | .focus { 85 | border-bottom: 3px solid #d26585; 86 | } 87 | 88 | .item { 89 | position: relative; 90 | width: 100%; 91 | height: 28px; 92 | background-color: white; 93 | outline: none; 94 | padding: 2px; 95 | } 96 | 97 | .item:focus, 98 | .item.select { 99 | background-color: #d26585; 100 | color: white; 101 | } 102 | 103 | .item img { 104 | height: 100%; 105 | float: left; 106 | outline: none; 107 | } 108 | 109 | .item .title { 110 | position: absolute; 111 | left: 109px; 112 | top: 3px; 113 | overflow: hidden; 114 | height: 36px; 115 | line-height: 18px; 116 | font-size: 12px; 117 | } 118 | 119 | .item .author { 120 | position: absolute; 121 | left: 130px; 122 | bottom: 2px; 123 | font-size: 12px; 124 | color: rgb(115, 115, 115); 125 | white-space: nowrap; 126 | } 127 | -------------------------------------------------------------------------------- /application/contribution/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0 auto; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | /* Soft Keys */ 10 | #softkeys { 11 | z-index: 100; 12 | position: fixed; 13 | bottom: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 30px; 17 | background: #dadada; 18 | padding: 3px 5px; 19 | } 20 | 21 | #softkeys > * { 22 | display: inline-block; 23 | width: 72px; 24 | padding: 0 5px; 25 | } 26 | 27 | #softkey-left, 28 | #softkey-right { 29 | font-weight: 400; 30 | font-size: 14px; 31 | color: #323232; 32 | line-height: 24px; 33 | text-align: left; 34 | } 35 | 36 | #softkey-right { 37 | text-align: right; 38 | line-height: 24px; 39 | } 40 | 41 | #softkey-center { 42 | font-weight: 600; 43 | font-size: 16px; 44 | width: 76px; 45 | color: #323232; 46 | text-align: center; 47 | } 48 | 49 | #container { 50 | overflow-x: hidden; 51 | overflow-y: auto; 52 | width: 100%; 53 | height: calc(100% - 30px); 54 | margin-bottom: 30px; 55 | } 56 | 57 | /* Item */ 58 | .items { 59 | width: 100%; 60 | height: calc(100% - 60px); 61 | overflow-x: hidden; 62 | overflow-y: auto; 63 | position: fixed; 64 | top: 30px; 65 | z-index: 1; 66 | } 67 | 68 | .item { 69 | position: relative; 70 | width: 100%; 71 | height: 60px; 72 | background-color: white; 73 | outline: none; 74 | } 75 | 76 | .item.select { 77 | background-color: #d26585; 78 | color: white; 79 | } 80 | 81 | .item img { 82 | height: 100%; 83 | float: left; 84 | outline: none; 85 | padding: 6px; 86 | } 87 | 88 | .item .title { 89 | position: absolute; 90 | left: 109px; 91 | top: 3px; 92 | overflow: hidden; 93 | height: 36px; 94 | line-height: 18px; 95 | font-size: 12px; 96 | } 97 | 98 | .item .author { 99 | position: absolute; 100 | left: 130px; 101 | bottom: 2px; 102 | font-size: 12px; 103 | color: rgb(115, 115, 115); 104 | white-space: nowrap; 105 | } 106 | 107 | .item .imgUP { 108 | width: 18px; 109 | height: 12px; 110 | position: absolute; 111 | left: 109px; 112 | bottom: 3px; 113 | font-size: 9.5px; 114 | border: 1px solid; 115 | border-radius: 2px; 116 | padding-bottom: 11px; 117 | text-align: center; 118 | color: rgb(115, 115, 115); 119 | } 120 | 121 | .item.select .author, 122 | .item.select .imgUP { 123 | color: white; 124 | } 125 | -------------------------------------------------------------------------------- /application/musicmenu/index.js: -------------------------------------------------------------------------------- 1 | let mid = 0, menuId = 0; 2 | $(function () { 3 | mid = $.getData('mid'); 4 | menuId = $.getQueryVar('id'); 5 | loadData(); 6 | document.activeElement.addEventListener('keydown', handleKeydown); 7 | }); 8 | function loadData() { 9 | var url = 'https://api.bilibili.com/audio/music-service-c/menus/' + menuId + '?mid=' + mid; 10 | var result = $.getApi(url); 11 | console.log(result); 12 | if (result.code == 0) { 13 | $('#cover').attr('src', result.data.menusRespones.coverUrl + '@96w_80h.jpg'); 14 | $('#title').text(result.data.menusRespones.title); 15 | $('#desc').text(result.data.menusRespones.intro); 16 | $('#play').text(result.data.menusRespones.playNum); 17 | var arr = result.data.songsList; 18 | if (arr != null) { 19 | for (var index = 0; index < arr.length; index++) { 20 | var html = '

' + arr[index].title + '

' + arr[index].author + '

'; 21 | $('.items').append(html); 22 | } 23 | } 24 | } 25 | else { 26 | alert('获取歌曲列表失败!' + result.message); 27 | } 28 | } 29 | function handleKeydown(e) { 30 | $.clearEvent(e); 31 | switch (e.key) { 32 | case 'ArrowUp': 33 | nav(-1); 34 | break; 35 | case 'ArrowDown': 36 | nav(1); 37 | break; 38 | case 'Q': 39 | case 'SoftLeft': 40 | const items = document.querySelectorAll('.item'); 41 | const targetElement = items[current]; 42 | var id = $(targetElement).attr("data-id"); 43 | window.location.href = '../songinfo/index.html?id=' + id; 44 | break; 45 | case 'E': 46 | case 'Backspace': 47 | case 'SoftRight': 48 | window.location.href = '../music/index.html'; 49 | break; 50 | } 51 | } 52 | var current = -1; 53 | function nav(move) { 54 | var next = current + move; 55 | const items = document.querySelectorAll('.item'); 56 | if (next >= items.length) { 57 | next = items.length - 1; 58 | } 59 | else if (next < 0) { 60 | next = 0; 61 | } 62 | const targetElement = items[next]; 63 | if (targetElement) { 64 | current = next; 65 | targetElement.focus(); 66 | $('.item').removeClass('select'); 67 | $(targetElement).addClass('select'); 68 | } 69 | } -------------------------------------------------------------------------------- /application/attention/index.js: -------------------------------------------------------------------------------- 1 | let userId = 0, total = 0, page = 1; 2 | 3 | $(function () { 4 | var id = $.getData('mid'); 5 | if (typeof id != 'undefined' && id != null && id != '') { 6 | userId = parseInt(id); 7 | loadFollow(); 8 | } 9 | document.activeElement.addEventListener('keydown', handleKeydown); 10 | }); 11 | 12 | function handleKeydown(e) { 13 | $.clearEvent(e); 14 | switch (e.key) { 15 | case 'ArrowUp': 16 | nav(-1); 17 | break; 18 | case 'ArrowDown': 19 | nav(1); 20 | break; 21 | case 'Q': 22 | case 'SoftLeft': 23 | const items = document.querySelectorAll('.item'); 24 | const targetElement = items[current]; 25 | window.location.href = '../user/index.html?mid=' + $(targetElement).attr('data-mid'); 26 | break; 27 | case 'Enter': 28 | page++; 29 | loadFollow(); 30 | break; 31 | case 'E': 32 | case 'Backspace': 33 | case 'SoftRight': 34 | window.location.href = '../user/index.html?mid=' + userId; 35 | break; 36 | } 37 | } 38 | 39 | var current = -1; 40 | function nav(move) { 41 | var next = current + move; 42 | const items = document.querySelectorAll('.item'); 43 | if (next >= items.length) { 44 | next = items.length - 1; 45 | } 46 | else if (next < 0) { 47 | next = 0; 48 | } 49 | const targetElement = items[next]; 50 | if (targetElement) { 51 | current = next; 52 | targetElement.focus(); 53 | $('.item').removeClass('select'); 54 | $(targetElement).addClass('select'); 55 | } 56 | } 57 | 58 | function loadFollow() { 59 | var url = 'https://api.bilibili.com/x/relation/followings?vmid=' + userId + '&ps=30&pn=' + page + '&order=desc'; 60 | var result = $.getApi(url); 61 | if (result.code == 0) { 62 | var arr = result.data.list; 63 | total = result.data.total; 64 | for (var index = 0; index < arr.length; index++) { 65 | var item = '
'; 67 | $('#container').append(item); 68 | } 69 | } 70 | else { 71 | alert('加载关注列表失败!' + result.message); 72 | } 73 | } -------------------------------------------------------------------------------- /application/setting/index.js: -------------------------------------------------------------------------------- 1 | let hasChange = false; 2 | $(function () { 3 | loadSetting(); 4 | document.activeElement.addEventListener('keydown', handleKeydown); 5 | }); 6 | function loadSetting() { 7 | try { 8 | var speed = $.getData('danmaku_speed'); 9 | if (speed == '') speed = 5; 10 | $('#danmaku_speed').val(speed); 11 | var qn = $.getData('video_qn'); 12 | if (qn == '') qn = 16; 13 | $("#video_qn").val(qn); 14 | var danmaku = $.getData('danmaku'); 15 | if (danmaku == '') danmaku = 0; 16 | $("#danmaku").prop("checked", danmaku == 1); 17 | } 18 | catch (e) { 19 | console.log(e); 20 | } 21 | } 22 | function saveSetting() { 23 | try { 24 | var speed = $('#danmaku_speed').val(); 25 | $.setData('danmaku_speed', speed); 26 | var qn = $("#video_qn").val(); 27 | $.setData('video_qn', qn); 28 | var danmaku = $('#danmaku').is(':checked'); 29 | $.setData('danmaku', danmaku ? 1 : 0); 30 | alert('保存成功!'); 31 | } 32 | catch (e) { 33 | console.log(e); 34 | alert('保存失败...' + e.message); 35 | } 36 | } 37 | function handleKeydown(e) { 38 | switch (e.key) { 39 | case 'ArrowUp': 40 | nav(-1); 41 | break; 42 | case 'ArrowDown': 43 | nav(1); 44 | break; 45 | case 'Q': 46 | case 'SoftLeft': 47 | saveSetting(); 48 | break; 49 | case 'E': 50 | case 'Backspace': 51 | case 'SoftRight': 52 | if (hasChange) { 53 | if (confirm('有未保存的设置,是否保存?')) 54 | saveSetting(); 55 | } 56 | window.location.href = '../index.html'; 57 | break; 58 | case 'Enter': 59 | if ($('#danmaku.select').length > 0) { 60 | var danmaku = $('#danmaku').is(':checked'); 61 | $("#danmaku").prop("checked", !danmaku); 62 | } 63 | break; 64 | } 65 | } 66 | var current = 0; 67 | function nav(move) { 68 | var next = current + move; 69 | const items = document.querySelectorAll('.item'); 70 | if (next >= items.length) { 71 | next = items.length - 1; 72 | } 73 | else if (next < 0) { 74 | next = 0; 75 | } 76 | const targetElement = items[next]; 77 | if (targetElement) { 78 | current = next; 79 | targetElement.focus(); 80 | $('.item').removeClass('select'); 81 | $(targetElement).addClass('select'); 82 | } 83 | } -------------------------------------------------------------------------------- /application/player/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 凯哔哩-播放器 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 |
27 |
28 | 33 |
34 |
35 |
36 | 标题加载中 37 |
38 |
39 |
40 | 41 | - 42 |
43 |
44 | 45 | - 46 |
47 |
48 |
49 |
50 |
51 | 52 | 加载中 53 |
54 |
55 | 56 | 加载中 57 |
58 |
59 | 60 | 加载中 61 |
62 |
63 |
64 |
65 |
66 |
67 | 68 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /application/lib/jquery.untils.js: -------------------------------------------------------------------------------- 1 | const textEncoder = new TextEncoder('utf-8'); 2 | const textDecoder = new TextDecoder('utf-8'); 3 | 4 | const readInt = function (buffer, start, len) { 5 | let result = 0; 6 | for (let i = len - 1; i >= 0; i--) 7 | result += Math.pow(256, len - i - 1) * buffer[start + i]; 8 | return result; 9 | } 10 | 11 | const writeInt = function (buffer, start, len, value) { 12 | let i = 0; 13 | while (i < len) { 14 | buffer[start + i] = value / Math.pow(256, len - i - 1); 15 | i++; 16 | } 17 | } 18 | 19 | const encode = function (str, op) { 20 | let data = textEncoder.encode(str); 21 | let packetLen = 16 + data.byteLength; 22 | let header = [0, 0, 0, 0, 0, 16, 0, 1, 0, 0, 0, op, 0, 0, 0, 1] 23 | writeInt(header, 0, 4, packetLen); 24 | return (new Uint8Array(header.concat(...data))).buffer 25 | } 26 | 27 | const decode = function (blob, callback) { 28 | let reader = new FileReader(); 29 | reader.onload = function (e) { 30 | let buffer = new Uint8Array(e.target.result) 31 | let result = {}; 32 | result.packetLen = readInt(buffer, 0, 4); 33 | result.headerLen = readInt(buffer, 4, 2); 34 | result.ver = readInt(buffer, 6, 2); 35 | result.op = readInt(buffer, 8, 4); 36 | result.seq = readInt(buffer, 12, 4); 37 | if (result.op === 5) { 38 | result.body = []; 39 | let offset = 0; 40 | while (offset < buffer.length) { 41 | let packetLen = readInt(buffer, offset + 0, 4) 42 | let headerLen = 16; 43 | let data = buffer.slice(offset + headerLen, offset + packetLen); 44 | let body = ''; 45 | try { 46 | body = textDecoder.decode(pako.inflate(data)); 47 | } 48 | catch (e) { 49 | body = textDecoder.decode(data) 50 | } 51 | if (body) { 52 | const group = body.split(/[\x00-\x1f]+/); 53 | group.forEach(item => { 54 | try { 55 | const parsedItem = JSON.parse(item); 56 | if (typeof parsedItem === 'object') 57 | result.body.push(parsedItem); 58 | } 59 | catch (e) { } 60 | }); 61 | } 62 | offset += packetLen; 63 | } 64 | } 65 | else if (result.op === 3) { 66 | result.body = { 67 | count: readInt(buffer, 16, 4) 68 | }; 69 | } 70 | callback(result); 71 | } 72 | reader.readAsArrayBuffer(blob); 73 | } -------------------------------------------------------------------------------- /application/allive/index.js: -------------------------------------------------------------------------------- 1 | let aid = 0, paid = 0, page = 1; 2 | $(function () { 3 | aid = $.getQueryVar('aid'); 4 | paid = $.getQueryVar('paid'); 5 | loadData(); 6 | document.activeElement.addEventListener('keydown', handleKeydown); 7 | }); 8 | function loadData() { 9 | var url = 'https://api.live.bilibili.com/room/v3/Area/getRoomList?actionKey=appkey&area_id=' + aid + '&cate_id=0&parent_area_id=' 10 | + paid + '&page=' + page + '&page_size=36&sort_type=online'; 11 | var result = $.getApi(url); 12 | if (result.code == 0) { 13 | var arr = result.data.list; 14 | if (arr != null) { 15 | for (var index = 0; index < arr.length; index++) { 16 | var uid = arr[index].uid; 17 | var nick = arr[index].uname; 18 | var sub = arr[index].online; 19 | var title = arr[index].title; 20 | var image = arr[index].cover; 21 | $('#container').append("
" + title + "
" + nick + "  在线:" 23 | + sub + "
") 24 | } 25 | } 26 | else { 27 | alert('没有更多了!'); 28 | } 29 | } 30 | else { 31 | alert('获取分区列表失败!' + result.message); 32 | } 33 | } 34 | function handleKeydown(e) { 35 | $.clearEvent(e); 36 | switch (e.key) { 37 | case 'ArrowUp': 38 | nav(-1); 39 | break; 40 | case 'ArrowDown': 41 | nav(1); 42 | break; 43 | case 'Enter': 44 | { 45 | page++; 46 | loadData(); 47 | break; 48 | } 49 | case 'Q': 50 | case 'SoftLeft': 51 | const items = document.querySelectorAll('.item'); 52 | const targetElement = items[current]; 53 | var uid = $(targetElement).attr("data-uid"); 54 | window.location.href = '../live/index.html?uid=' + uid; 55 | break; 56 | case 'E': 57 | case 'Backspace': 58 | case 'SoftRight': 59 | window.location.href = '../livelist/index.html'; 60 | break; 61 | } 62 | } 63 | var current = -1; 64 | function nav(move) { 65 | var next = current + move; 66 | const items = document.querySelectorAll('.item'); 67 | if (next >= items.length) { 68 | next = items.length - 1; 69 | } 70 | else if (next < 0) { 71 | next = 0; 72 | } 73 | const targetElement = items[next]; 74 | if (targetElement) { 75 | current = next; 76 | targetElement.focus(); 77 | $('.item').removeClass('select'); 78 | $(targetElement).addClass('select'); 79 | } 80 | } -------------------------------------------------------------------------------- /application/contribution/index.js: -------------------------------------------------------------------------------- 1 | let userId = 0, page = 1; 2 | let self = false; 3 | 4 | $(function () { 5 | var mid = $.getQueryVar('mid'); 6 | if (mid === false) { 7 | self = true; 8 | userId = $.getData('mid'); 9 | } 10 | else { 11 | userId = mid; 12 | } 13 | loadResource(); 14 | document.activeElement.addEventListener('keydown', handleKeydown); 15 | }); 16 | 17 | function playV() { 18 | const items = document.querySelectorAll('.item'); 19 | const targetElement = items[current]; 20 | var aid = $(targetElement).attr('data-aid'); 21 | var bvid = $(targetElement).attr('data-bvid'); 22 | var cid = $(targetElement).attr('data-cid'); 23 | window.location.href = '../player/index.html?aid=' + aid + '&bvid=' + bvid + '&cid=' + cid + '&type=contribution&mid=' + userId; 24 | } 25 | 26 | function loadResource() { 27 | var url = 'https://api.bilibili.com/x/space/arc/search?mid=' + userId + '&ps=30&tid=0&pn=' + page + '&keyword=&order=pubdate'; 28 | var result = $.getApi(url); 29 | if (result.code == 0) { 30 | var vlist = result.data.list.vlist; 31 | if (vlist != null && vlist.length > 0) { 32 | for (var index = 0; index < vlist.length; index++) { 33 | var item = vlist[index]; 34 | $('#container').append("
" + item.title + "
UP
" 36 | + item.author + "
"); 37 | } 38 | } 39 | else { 40 | $('#container').append('') 41 | } 42 | } 43 | else { 44 | alert('获取投稿内容失败!' + result.message); 45 | } 46 | } 47 | 48 | function handleKeydown(e) { 49 | $.clearEvent(e); 50 | switch (e.key) { 51 | case 'ArrowUp': 52 | nav(-1); 53 | break; 54 | case 'ArrowDown': 55 | nav(1); 56 | break; 57 | case 'Q': 58 | case 'SoftLeft': 59 | playV(); 60 | break; 61 | case 'E': 62 | case 'Backspace': 63 | case 'SoftRight': 64 | window.location.href = '../user/index.html?mid=' + userId; 65 | break; 66 | } 67 | } 68 | 69 | var current = 0; 70 | function nav(move) { 71 | var next = current + move; 72 | const items = document.querySelectorAll('.item'); 73 | if (next >= items.length) { 74 | next = items.length - 1; 75 | } 76 | else if (next < 0) { 77 | next = 0; 78 | } 79 | const targetElement = items[next]; 80 | if (targetElement) { 81 | current = next; 82 | targetElement.focus(); 83 | $('.item').removeClass('select'); 84 | $(targetElement).addClass('select'); 85 | } 86 | } -------------------------------------------------------------------------------- /application/collection/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | #container { 9 | overflow-x: hidden; 10 | overflow-y: auto; 11 | width: 100%; 12 | height: calc(100% - 30px); 13 | margin-bottom: 30px; 14 | } 15 | 16 | /* Soft Keys */ 17 | #softkeys { 18 | z-index: 100; 19 | position: fixed; 20 | bottom: 0; 21 | left: 0; 22 | width: 100%; 23 | height: 30px; 24 | background: #dadada; 25 | padding: 3px 5px; 26 | } 27 | 28 | #softkeys>* { 29 | display: inline-block; 30 | width: 72px; 31 | padding: 0 5px; 32 | } 33 | 34 | #softkey-left, 35 | #softkey-right { 36 | font-weight: 400; 37 | font-size: 14px; 38 | color: #323232; 39 | line-height: 24px; 40 | line-height: 24px; 41 | } 42 | 43 | #softkey-right { 44 | text-align: right; 45 | line-height: 24px; 46 | } 47 | 48 | #softkey-center { 49 | font-weight: 600; 50 | font-size: 16px; 51 | width: 76px; 52 | color: #323232; 53 | text-align: center; 54 | } 55 | 56 | #menu { 57 | display: none; 58 | z-index: 100; 59 | background: rgba(00, 00, 00, 0.5); 60 | position: fixed; 61 | left: 0; 62 | top: 0; 63 | width: 100%; 64 | height: 100%; 65 | } 66 | 67 | #menucontainer { 68 | position: fixed; 69 | bottom: 30px; 70 | left: 0px; 71 | width: 98%; 72 | background: white; 73 | margin: 3px; 74 | list-style: none; 75 | } 76 | 77 | .menuitem { 78 | position: relative; 79 | background-color: white; 80 | width: 100%; 81 | outline: none; 82 | height: 30px; 83 | padding-left: 5px; 84 | line-height: 30px; 85 | } 86 | 87 | .menuitem.select { 88 | background-color: #d26585; 89 | color: white; 90 | } 91 | 92 | /* Item */ 93 | .items { 94 | width: 100%; 95 | height: calc(100% - 60px); 96 | overflow-x: hidden; 97 | overflow-y: auto; 98 | position: fixed; 99 | top: 30px; 100 | z-index: 1; 101 | } 102 | 103 | .item { 104 | position: relative; 105 | width: 100%; 106 | height: 60px; 107 | background-color: white; 108 | outline: none; 109 | } 110 | 111 | .item.select { 112 | background-color: #d26585; 113 | color: white; 114 | } 115 | 116 | .item img { 117 | height: 100%; 118 | float: left; 119 | outline: none; 120 | } 121 | 122 | .item .title { 123 | position: absolute; 124 | left: 109px; 125 | top: 3px; 126 | overflow: hidden; 127 | height: 36px; 128 | line-height: 18px; 129 | font-size: 12px; 130 | } 131 | 132 | .item .author { 133 | position: absolute; 134 | left: 130px; 135 | bottom: 2px; 136 | font-size: 12px; 137 | color: rgb(115, 115, 115); 138 | white-space: nowrap; 139 | } 140 | 141 | .item .imgUP { 142 | width: 18px; 143 | height: 12px; 144 | position: absolute; 145 | left: 109px; 146 | bottom: 3px; 147 | font-size: 9.5px; 148 | border: 1px solid; 149 | border-radius: 2px; 150 | padding-bottom: 11px; 151 | text-align: center; 152 | color: rgb(115, 115, 115); 153 | } 154 | 155 | .item.select .author, 156 | .item:focus .imgUP { 157 | color: white; 158 | } -------------------------------------------------------------------------------- /application/songinfo/index.js: -------------------------------------------------------------------------------- 1 | let sid = 0, mid = 0; 2 | let audio = null; 3 | $(function () { 4 | audio = new Audio(); 5 | audio.loop = true; 6 | audio.onplay = function () { 7 | $('#softkey-center').text('暂停'); 8 | }; 9 | audio.onpause = function () { 10 | $('#softkey-center').text('播放'); 11 | }; 12 | sid = $.getQueryVar('id'); 13 | mid = $.getData('mid'); 14 | var surl = 'https://api.bilibili.com/audio/music-service-c/url?mid=' + mid + '&privilege=2&quality=1&songid=' + sid; 15 | $.getApiAsync(surl, function (data) { 16 | if (data.code == 0) { 17 | if (data.data.cdns != null && data.data.cdns.length > 0) { 18 | var uri = data.data.cdns[0]; 19 | playMusic(uri); 20 | } 21 | else { 22 | alert('获取歌曲播放地址失败!'); 23 | } 24 | } 25 | else { 26 | alert('获取歌曲播放地址失败!' + data.message); 27 | } 28 | }); 29 | loadData(); 30 | document.activeElement.addEventListener('keydown', handleKeydown); 31 | }); 32 | function playMusic(uri) { 33 | audio.pause(); 34 | audio.src = uri; 35 | audio.play(); 36 | } 37 | function playOrPause() { 38 | if (audio.paused) 39 | audio.play(); 40 | else 41 | audio.pause(); 42 | } 43 | function loadData() { 44 | var url = 'https://api.bilibili.com/audio/music-service-c/songs/playing?mid=' + mid + '&song_id=' + sid; 45 | var result = $.getApi(url); 46 | if (result.code == 0) { 47 | $('#cover').attr('src', result.data.cover_url + '@96w_80h.jpg'); 48 | $('#title').text(result.data.title); 49 | $('#play').text(result.data.play_count); 50 | $('#collection').text(result.data.collect_count); 51 | $('#share').text(result.data.snum); 52 | $('#songName').text(result.data.intro); 53 | $('#uface').attr('src', result.data.up_img + '@64w_64h.jpg'); 54 | $('#uname').text(result.data.up_name); 55 | $('#pt').text(result.data.ctime_str); 56 | } 57 | else { 58 | alert('获取歌曲信息失败!' + result.message); 59 | } 60 | } 61 | function handleKeydown(e) { 62 | $.clearEvent(e); 63 | switch (e.key) { 64 | case 'ArrowUp': 65 | nav(-1); 66 | break; 67 | case 'ArrowDown': 68 | nav(1); 69 | break; 70 | case '2': 71 | navigator.volumeManager.requestUp(); 72 | break; 73 | case '8': 74 | navigator.volumeManager.requestDown(); 75 | break; 76 | case '4': 77 | seekTo(-1); 78 | break; 79 | case '6': 80 | seekTo(1); 81 | break; 82 | case 'Enter': 83 | playOrPause(); 84 | break; 85 | case 'E': 86 | case 'Backspace': 87 | case 'SoftRight': 88 | window.location.href = '../music/index.html'; 89 | break; 90 | } 91 | } 92 | function seekTo(type) { 93 | try { 94 | if (!audio.paused && !isNaN(audio.duration)) { 95 | var next = audio.currentTime + (type * 5); 96 | if (next < 0) 97 | next = 0; 98 | else if (next > audio.duration) 99 | next = audio.duration; 100 | audio.currentTime = next; 101 | audio.play(); 102 | } 103 | } 104 | catch (e) { 105 | console.log(e); 106 | } 107 | } -------------------------------------------------------------------------------- /application/lib/md5.min.js: -------------------------------------------------------------------------------- 1 | !function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((c=d(d(t,n),d(e,u)))<<(f=o)|c>>>32-f,r);var c,f}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function i(n,t){var r,e,o,u;n[t>>5]|=128<>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h>5]>>>e%32&255);return t}function h(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e>5]|=(255&n.charCodeAt(e/8))<>>4&15)+r.charAt(15&t);return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return a(i(h(t=r(n)),8*t.length));var t}function u(n,t){return function(n,t){var r,e,o=h(n),u=[],c=[];for(u[15]=c[15]=void 0,16 * { 139 | display: inline-block; 140 | width: 72px; 141 | padding: 0 5px; 142 | } 143 | 144 | #softkey-left, 145 | #softkey-right { 146 | font-weight: 400; 147 | font-size: 14px; 148 | color: #323232; 149 | } 150 | 151 | #softkey-right { 152 | text-align: right; 153 | } 154 | 155 | #softkey-center { 156 | font-weight: 600; 157 | font-size: 16px; 158 | width: 76px; 159 | color: #323232; 160 | text-align: center; 161 | } 162 | 163 | #menu { 164 | display: none; 165 | z-index: 100; 166 | background: rgba(00, 00, 00, 0.5); 167 | position: fixed; 168 | left: 0; 169 | top: 0; 170 | width: 100%; 171 | height: 100%; 172 | } 173 | 174 | #menucontainer { 175 | position: fixed; 176 | bottom: 30px; 177 | left: 0px; 178 | width: 98%; 179 | background: white; 180 | margin: 3px; 181 | } 182 | 183 | .menuitem { 184 | position: relative; 185 | background-color: white; 186 | width: 100%; 187 | outline: none; 188 | height: 30px; 189 | padding-left: 5px; 190 | line-height: 30px; 191 | } 192 | 193 | .menuitem:focus { 194 | background-color: #d26585; 195 | color: white; 196 | } 197 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bilibili_kaios 2 | 3 | bilibili for kaios 4 | 5 | 如需使用请下载 release 版本,master 分支可能存在实验性特性! 6 | 7 | | 文件夹 | 用途 | 8 | | :-: | :--: | 9 | | allive | 直播分区 | 10 | | attention | 关注的人 | 11 | | bandetail | 番剧详细 | 12 | | bangmi | 番剧首页 | 13 | | collection | 收藏夹 | 14 | | contribution | 用户投稿 | 15 | | dydetail | 动态详细 | 16 | | dynamic | 动态 | 17 | | live | 直播间页面 | 18 | | lives | 直播列表 | 19 | | music | 音乐首页 | 20 | | player | 播放页面 | 21 | | user | 用户页面 | 22 | | web | 网站页面 | 23 | | lib | 引用库 | 24 | 25 | ## TODO List 26 | 27 | - [ ] FLV 播放支持(最高 720P、但实测在线播放最高 480P,否则容易崩溃) 28 | 29 | ## Update 30 | 31 |
32 | 更新日志 33 | 34 | ### 1.0 35 | 版本:1.0 36 | 更新时间:2020-10-3 37 | 更新简介: 38 | 因为电脑文件丢失,不得不重写软件。更改了配色(从粉色变为蓝色)和原来丑不拉几的UI,增加了可用左右键操作的顶栏。提升了代码的可维护性。 39 | 主要功能如下: 40 | 1.获取B站电脑端首页视频 41 | 2.播放视频和观看弹幕(透明度不可调,弹幕无法关闭) 42 | 更新内容: 43 | 1.修改了UI 44 | 2.由使用
存储临时数据改为了用列表存储(我都不知道我是怎么想到用自定义标签的阴间方法的……) 45 | 3.提升了网络体验(更换服务器) 46 | 47 | 48 | ### 1.1 49 | 版本:1.1 50 | 更新时间:2020-10-31 51 | 更新简介: 52 | 为了让大家快点用上新版本,再加上马上期中考,更新有些仓促,新增的功能比较少。 53 | 本次更新添加了“关注”功能,完整的直播观看系统在做了 54 | 更新内容: 1.找回了关注功能,能在本地直接使用 UID 添加喜欢的 UP 主(不能和 B 站账号同步!) 2.在“直播”选项卡按“观看”键可以试试正在制作的看直播功能(用来测试的是“KPL 官方赛事直播间”),目前看直播功能如下: 1.如果 UP 主有在直播,可以正常低画质观看直播流(高画质 8110 带不动) 2.全屏观看直播 55 | 56 | 57 | ### 1.2 58 | 版本:1.2 59 | 更新时间:2021-1-30 60 | 更新简介: 61 | 这次更新间隔有点长,因为我有严重拖延症(沉迷 Arcara)。这次更新改进了一些细节,填了一些坑。 62 | 视频暂停神马的还暂时做不到(能获取到视频的文件位置,但叔叔做了跨域限制,只有 B 站自己的网址能正常访问。转发视频流神马的小带宽吃不消 Σ:3,以后试一下伪装包名) 63 | 有反馈说弹幕太多了看不到视频,含泪把弹幕关闭了 64 | 更新内容: 65 | 1.“首页推荐”选项卡更名“热门” 2.修复了无法正常退出程序的 bug 3.视频播放页面可以查看视频详情了 4.软件启动会自动检查更新,下一次更新可以直接在手机安装了(前提是安装了 Omni SD) 5.在非全屏页面下能看到状态栏了 6.可以观看已关注的 UP 主的直播流(暂时不提供 UP 主是否正在直播的查询)(反正出错你就退出来 Σ;3) 7.关闭了弹幕功能 8.视频播放窗口的音量调节按钮改到了右软键(直播页面仍然是 2 键) 66 | 67 | 68 | ### 1.3 69 | 版本:1.3 70 | 更新时间:2021-3-14 71 | 更新简介: 72 | 【应急更新】云服务器到期了,学生机续费次数用完了(哭)。马上之前的版本用不了了,现在用的是我自己搭建的服务器,使用体验会非常差,希望大家可以理解。 73 | 这期间应用响应时间多半在 10 秒以上,希望大家能等一下…… 74 | 可能会有家里人拔电源线的情况,希望大家能够理解…… 75 | 更新内容: 1.更换了服务器 76 | 77 | 78 | ### 1.4 79 | 版本:1.4 80 | 更新时间:等亿下 81 | 更新简介: 82 | 83 | 84 | 85 | 更新内容: 1.能显示关注的 UP 主的完整的视频列表 2.增加了搜索视频的功能 3.能播放分 P 视频的其它分集 4.能手动输入直播间号观看直播视频 86 | 1.4 更新补充: 87 | 更改接口请求方式,直接请求 b 站官方接口,不再由服务器中转! 88 | 89 | 90 | ### 1.5 91 | 版本:1.5 92 | 更新人:zixing 93 | 更新内容: 1.修改快捷键,播放界面 2 键提高音量,8 键降低音量。 2.可以删除添加或清空关注的主播和直播内容 3.直播更改为通过直播间 id 或者直播的用户进行添加,可以删除添加的直播间 4.注意:本版本更新更改了关注和直播的数据结构,会自动转化旧版的数据! 5.修复视频评论内容,支持下一页操作 6.修改获取图片时的默认分辨率,使网络加载图片更加顺畅 7.主页视频支持切换三天热点或者七天热点 8.搜索支持下一页操作 9.查看 UP 主视频支持下一页操作 94 | 95 | 96 | ### 1.6 97 | 版本:1.6 98 | 更新人:zixing 99 | 更新内容: 1.现在直播可以加载出直播间信息并且可以查看直播弹幕了(需要手动刷新) 2.切换菜单时记住当前选中的项目。 3.视频可以暂停了(解析了视频直链,不再使用 B 站播放器) 100 | 101 | 102 | ### 1.8 103 | 版本 1.8 104 | 更新人:michael_eddy 1.现在你可以登录了。 2.登录后的一些操作:关注列表、评论、收藏夹、投稿。 3.支持看直播和发弹幕。 4.支持通过按钮“4”、“6”进行视频“快退”、“快进”。 5.支持番剧、国创、直播列表/分区。 6.番剧可以用 480P 看了,虽然支持 720P 但是实测很容易崩溃 105 | 106 | 107 | ### 1.8.1 108 | 版本 1.8.1 109 | 更新人:michael_eddy 1.添加视频弹幕,可以在分区-设置中开启或者关闭 110 | 111 | 112 | ### 1.8.2 113 | 版本 1.8.2 114 | 更新人:michael_eddy 1.添加直播弹幕,可以在分区-设置中开启或者关闭(视频弹幕关闭则直播弹幕也会关闭,但列表中弹幕仍会更新) 115 | 116 | ### 1.8.3 117 | 版本 1.8.3 118 | 更新人:michael_eddy 1.修改主界面去掉旧无用代码提高效率 2.增加播放器失败重新播放功能 119 | 120 | ### 1.8.5 121 | 版本 1.8.5 122 | 更新时间:2022-9-3 123 | 更新人:白羊座的一只狼(TonyLang) 124 | 更新内容:紧急修复了视频搜索功能的API调用错误。该错误由B站服务端升级引起。 125 | 126 | ### 1.8.6 127 | 版本 1.8.6 128 | 更新时间:2023-3-18 129 | 更新人:zixing 130 | 更新内容:修复了登录不能使用的问题,需要使用手机端哔哩哔哩app扫码登录 131 | 132 | ### 1.8.7 133 | 版本 1.8.7 134 | 更新时间:2023-3-18 135 | 更新人:zixing 136 | 更新内容:紧急修复协议问题 137 | 138 | ### 1.8.8 139 | 更新时间:2024-3-26 140 | 更新人:zixing 141 | 更新内容: 142 | 1.修复登录页面的相关错误 143 | 2.修复直播页面的错误问题 144 | 3.其他小问题修复 145 | 146 |
147 | 148 | -------------------------------------------------------------------------------- /application/live/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | /* Tab */ 9 | .tab { 10 | width: 100%; 11 | height: 30px; 12 | position: fixed; 13 | top: 150px; 14 | background-color: white; 15 | z-index: 2; 16 | } 17 | 18 | .tab li { 19 | float: left; 20 | list-style: none; 21 | margin: 7.5; 22 | font-size: 14px; 23 | position: relative; 24 | top: -3px; 25 | } 26 | 27 | .focus { 28 | border-bottom: 3px solid #d26585; 29 | } 30 | 31 | /* Item */ 32 | .items { 33 | position: absolute; 34 | width: 100%; 35 | height: 110px; 36 | overflow: hidden; 37 | position: fixed; 38 | top: 30px; 39 | z-index: 1; 40 | top: 180px; 41 | } 42 | 43 | .item { 44 | position: relative; 45 | width: 100%; 46 | height: auto; 47 | padding: 5px; 48 | background-color: white; 49 | outline: none; 50 | } 51 | 52 | .item:focus { 53 | background-color: #d26585; 54 | color: white; 55 | } 56 | 57 | /* Item's inner */ 58 | .item img { 59 | height: 100%; 60 | width: 106px; 61 | float: left; 62 | outline: none; 63 | } 64 | 65 | .item .title { 66 | position: absolute; 67 | left: 109px; 68 | top: 3px; 69 | font-size: 12px; 70 | } 71 | 72 | .item .author { 73 | position: absolute; 74 | left: 130px; 75 | bottom: 2px; 76 | font-size: 12px; 77 | color: rgb(115, 115, 115); 78 | white-space: nowrap; 79 | } 80 | 81 | .item .imgUP { 82 | width: 18px; 83 | height: 12px; 84 | position: absolute; 85 | left: 109px; 86 | bottom: 3px; 87 | font-size: 9.5px; 88 | border: 1px solid; 89 | border-radius: 2px; 90 | padding-bottom: 11px; 91 | text-align: center; 92 | color: rgb(115, 115, 115); 93 | } 94 | 95 | .item:focus .author { 96 | color: white; 97 | } 98 | 99 | .item:focus .imgUP { 100 | color: white; 101 | } 102 | 103 | #title { 104 | position: absolute; 105 | top: 5px; 106 | left: 10px; 107 | font-size: 14px; 108 | } 109 | 110 | #info { 111 | position: absolute; 112 | bottom: 5px; 113 | left: 10px; 114 | font-size: 12px; 115 | } 116 | 117 | /* Player */ 118 | .player { 119 | width: 240px; 120 | height: 150px; 121 | } 122 | 123 | .player_fullscreen { 124 | width: 320px; 125 | height: 240px; 126 | position: fixed; 127 | transform: rotate(90deg); 128 | top: 40px; 129 | left: -40px; 130 | } 131 | 132 | #player { 133 | background-color: black; 134 | z-index: 300; 135 | } 136 | /* Soft Keys */ 137 | #softkeys { 138 | z-index: 100; 139 | position: fixed; 140 | bottom: 0; 141 | left: 0; 142 | width: 100%; 143 | height: 30px; 144 | background: #dadada; 145 | padding: 3px 5px; 146 | } 147 | 148 | #softkeys > * { 149 | display: inline-block; 150 | width: 72px; 151 | padding: 0 5px; 152 | } 153 | 154 | #softkey-left, 155 | #softkey-right { 156 | font-weight: 400; 157 | font-size: 14px; 158 | color: #323232; 159 | } 160 | 161 | #softkey-right { 162 | text-align: right; 163 | } 164 | 165 | #softkey-center { 166 | font-weight: 600; 167 | font-size: 16px; 168 | width: 76px; 169 | color: #323232; 170 | text-align: center; 171 | } 172 | 173 | .itemcomment { 174 | float: left; 175 | position: relative; 176 | padding: 2px 5px; 177 | width: 100%; 178 | background-color: white; 179 | outline: none; 180 | font-size: 14px; 181 | } 182 | .comment { 183 | float: left; 184 | position: relative; 185 | padding: 2px 0; 186 | width: 100%; 187 | outline: none; 188 | max-height: 60px; 189 | } 190 | .itemcomment:focus { 191 | background-color: #d26585; 192 | color: white; 193 | } 194 | 195 | canvas { 196 | top: 0 !important; 197 | left: 0 !important; 198 | z-index: 99 !important; 199 | position: fixed !important; 200 | } 201 | -------------------------------------------------------------------------------- /application/live/webscoket.js: -------------------------------------------------------------------------------- 1 | class BiliSocket { 2 | constructor(id) { 3 | this.danmaku = $.getData('danmaku'); 4 | if (this.danmaku == '') this.danmaku = 0; 5 | this.roomid = parseInt(id); 6 | } 7 | draw(rootElementId, elementId) { 8 | if (this.danmaku != 0) { 9 | window.danmaku = new Danmaku({ 10 | container: document.getElementById(rootElementId), 11 | media: document.getElementById(elementId), 12 | engine: 'canvas', 13 | speed: 80 14 | }); 15 | } 16 | } 17 | server() { 18 | var url = 'https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=' + this.roomid; 19 | var result = $.getApi(url); 20 | if (result.code == 0) { 21 | var token = result.data.token; 22 | var info = result.data.host_server_list[0]; 23 | return { token: token, host: info.host, port: info.ws_port }; 24 | } 25 | else { 26 | return { token: '', host: 'broadcastlv.chat.bilibili.com', port: 2244 }; 27 | } 28 | } 29 | listen(callback) { 30 | try { 31 | var classObj = this; 32 | var info = this.server(); 33 | var ws = new WebSocket('ws://' + info.host + ':' + info.port + '/sub'); 34 | ws.onopen = function () { 35 | var uid = $.getData('mid'); 36 | if (uid == '') 37 | uid = 0; 38 | var data = { 39 | protover: 2, 40 | platform: "web", 41 | key: info.token, 42 | uid: parseInt(uid), 43 | roomid: classObj.roomid 44 | }; 45 | ws.send(encode(JSON.stringify(data), 7)); 46 | }; 47 | ws.onmessage = function (event) { 48 | try { 49 | decode(event.data, function (packet) { 50 | if (packet.op == 5) { 51 | packet.body.forEach((body) => { 52 | switch (body.cmd) { 53 | case 'DANMU_MSG': { 54 | var msg = body.info[1]; 55 | var ct = $.toDateTimeString(body.info[9].ts); 56 | callback({ 57 | content: { 58 | msg: msg, 59 | time: ct, 60 | user: body.info[2][1] 61 | }, 62 | name: 'danmaku' 63 | }); 64 | if (classObj.danmaku != 0) { 65 | window.danmaku.emit({ 66 | text: msg, 67 | style: { 68 | font: '12px', 69 | fillStyle: '#fff' 70 | } 71 | }); 72 | } 73 | break; 74 | } 75 | } 76 | }); 77 | } 78 | }); 79 | } 80 | catch (e) { 81 | console.log(e) 82 | } 83 | }; 84 | ws.onclose = function (event) { 85 | alert('弹幕服务连接断开!'); 86 | }; 87 | setInterval(function () { 88 | ws.send(encode('', 2)); 89 | }, 30000); 90 | } 91 | catch (e) { 92 | console.log(e) 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /application/livelist/index.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | loadData(); 3 | document.activeElement.addEventListener('keydown', handleKeydown); 4 | }); 5 | function loadData() { 6 | var url = 'https://api.live.bilibili.com/xlive/app-interface/v2/index/getAllList?device=android&rec_page=1&relation_page=1&scale=xxhdpi'; 7 | var result = $.getApi(url); 8 | if (result.code == 0) { 9 | var rooms = result.data.room_list; 10 | if (rooms != null) { 11 | for (var index = 0; index < rooms.length; index++) { 12 | var lists = rooms[index].list; 13 | var module_info = rooms[index].module_info; 14 | var aid = module_info.link.match(new RegExp(/&area_id=(\d+)/)); 15 | var paid = module_info.link.match(new RegExp(/parent_area_id=(\d+)/)); 16 | aid = $.getKeyValue(aid); 17 | paid = $.getKeyValue(paid); 18 | var html = '
' + module_info.title + '
'; 19 | if (lists != null) { 20 | for (var j = 0; j < lists.length; j++) { 21 | html += '
'; 22 | html += '

' + lists[j].title + '

'; 23 | html += '
'; 24 | } 25 | } 26 | html += '
'; 27 | $('#container').append(html); 28 | } 29 | } 30 | } 31 | else { 32 | alert('获取直播信息失败!' + result.message); 33 | } 34 | } 35 | function handleKeydown(e) { 36 | $.clearEvent(e); 37 | switch (e.key) { 38 | case 'ArrowUp': 39 | nav(-1); 40 | break; 41 | case 'ArrowDown': 42 | nav(1); 43 | break; 44 | case 'ArrowRight': 45 | tab(1); 46 | break; 47 | case 'ArrowLeft': 48 | tab(-1); 49 | break; 50 | case 'Q': 51 | case 'SoftLeft': 52 | { 53 | const items = document.querySelectorAll('.item'); 54 | const targetElement = items[current]; 55 | var index = $(targetElement).attr('data-index'); 56 | if (index) { 57 | var item = $(targetElement).find('.roomlist').children()[index]; 58 | var uid = $(item).attr('data-id'); 59 | window.location.href = '../live/index.html?uid=' + uid; 60 | } 61 | break; 62 | } 63 | case 'Enter': { 64 | const items = document.querySelectorAll('.item'); 65 | const targetElement = items[current]; 66 | var aid = $(targetElement).attr('data-aid'); 67 | var paid = $(targetElement).attr('data-paid'); 68 | window.location.href = '../allive/index.html?aid=' + aid + '&paid=' + paid; 69 | break; 70 | } 71 | case 'E': 72 | case 'Backspace': 73 | case 'SoftRight': 74 | window.location.href = '../index.html'; 75 | break; 76 | } 77 | } 78 | var current = -1; 79 | function nav(move) { 80 | var next = current + move; 81 | const items = document.querySelectorAll('.item'); 82 | if (next >= items.length) { 83 | next = items.length - 1; 84 | } 85 | else if (next < 0) { 86 | next = 0; 87 | } 88 | const targetElement = items[next]; 89 | if (targetElement) { 90 | current = next; 91 | targetElement.focus(); 92 | $('.item').removeClass('select'); 93 | $(targetElement).addClass('select'); 94 | } 95 | } 96 | function tab(move) { 97 | const items = document.querySelectorAll('.item'); 98 | const targetElement = items[current]; 99 | var index = $(targetElement).attr('data-index'); 100 | if (!index) 101 | index = -1; 102 | else 103 | index = parseInt(index); 104 | var next = index + move; 105 | if (next < 0) next = 0; 106 | var root = $(targetElement).find('.roomlist'); 107 | var child = $(root).children(); 108 | if (child != null) { 109 | if (next > child.length) 110 | next = 0; 111 | var container = child[next]; 112 | $(child[index]).removeClass('select'); 113 | $(container).addClass('select'); 114 | $(targetElement).attr('data-index', next); 115 | var scrollLeft = $(container).width() * next; 116 | root[0].scroll(scrollLeft, 0); 117 | } 118 | } -------------------------------------------------------------------------------- /application/bandetail/index.js: -------------------------------------------------------------------------------- 1 | let id = '', season_type = 0; 2 | var tab_location = 1;//设置header位置 3 | $(function () { 4 | id = $.getQueryVar('id'); 5 | if (id) { 6 | var url = 'https://api.bilibili.com/pgc/view/app/season?season_id=' + id; 7 | var result = $.getApi(url); 8 | if (result.code == 0) { 9 | $('#cover').attr('src', result.result.cover + '@192w_120h.jpg'); 10 | $('#title').text(result.result.title); 11 | $('#play').text(result.result.stat.play); 12 | $('#focus').text(result.result.stat.followers); 13 | $('#time').text(result.result.new_ep.desc); 14 | setTimeout(function () { 15 | console.log(result.result.episodes) 16 | var episodes = result.result.episodes.sort(orderBy); 17 | season_type = result.result.type; 18 | if (episodes != null) { 19 | for (var index = 0; index < episodes.length; index++) { 20 | var html = '
' 21 | + episodes[index].title + '
'; 22 | $('.items').append(html); 23 | } 24 | } 25 | }, 80); 26 | } 27 | else { 28 | alert('获取番剧信息失败' + result.message); 29 | } 30 | } 31 | else { 32 | alert('获取番剧信息失败!'); 33 | window.location.href = '../bangmi/index.html'; 34 | } 35 | document.activeElement.addEventListener('keydown', handleKeydown); 36 | }); 37 | function orderBy(item1, item2) { 38 | var v1 = parseInt(item1.ep_index); 39 | var v2 = parseInt(item2.ep_index); 40 | if (v1 < v2) 41 | return 1; 42 | else if (v1 > v2) 43 | return -1; 44 | else 45 | return 0; 46 | } 47 | function selectItem() { 48 | const items = document.querySelectorAll('.item'); 49 | const targetElement = items[current]; 50 | var aid = $(targetElement).attr('data-aid'); 51 | var cid = $(targetElement).attr('data-cid'); 52 | var bvid = $(targetElement).attr('data-bid'); 53 | window.location.href = '../player/index.html?aid=' + aid + '&bvid=' + bvid + '&cid=' + cid + '&season_type=' + season_type + '&type=bandetail&id=' + id; 54 | } 55 | function load() { 56 | switch (tab_location) { 57 | case 0: { 58 | $('.items').hide(); 59 | $('#container').show(); 60 | break; 61 | } 62 | case 1: { 63 | $('.items').show(); 64 | $('#container').hide(); 65 | break; 66 | } 67 | } 68 | } 69 | function handleKeydown(e) { 70 | $.clearEvent(e); 71 | switch (e.key) { 72 | case 'ArrowRight': 73 | tab(1); 74 | break; 75 | case 'ArrowLeft': 76 | tab(-1); 77 | break; 78 | case 'ArrowUp': 79 | nav(-1); 80 | break; 81 | case 'ArrowDown': 82 | nav(1); 83 | break; 84 | case 'Q': 85 | case 'SoftLeft': 86 | selectItem(); 87 | break; 88 | case 'E': 89 | case 'Backspace': 90 | case 'SoftRight': 91 | window.location.href = '../bangmi/index.html'; 92 | break; 93 | } 94 | } 95 | function tab(move) { 96 | var currentIndex = parseInt($('.focus').attr('tabIndex')); //获取目前带有focus的元素的tabIndex 97 | var next = currentIndex + move; //设置移动位置 98 | if (next > 1) { 99 | next = 0; 100 | } 101 | if (next < 0) { 102 | next = 1; 103 | } 104 | var items = document.querySelectorAll('li'); //遍历所有的li元素 105 | var targetElement = items[next]; //将位置与遍历结果对应 106 | if (targetElement == undefined) { //如果没有可供选择的目标 107 | return; //中止函数 108 | } 109 | $('.focus').attr("class", ""); //清除原有效果 110 | targetElement.className = "focus"; //设置新效果 111 | tab_location = next; 112 | load(); 113 | } 114 | var current = 0; 115 | function nav(move) { 116 | var next = current + move; 117 | const items = document.querySelectorAll('.item'); 118 | if (next >= items.length) { 119 | next = items.length - 1; 120 | } 121 | else if (next < 0) { 122 | next = 0; 123 | } 124 | const targetElement = items[next]; 125 | if (targetElement) { 126 | current = next; 127 | targetElement.focus(); 128 | $('.item').removeClass('select'); 129 | $(targetElement).addClass('select'); 130 | } 131 | if (next == 0) 132 | $('.items').scrollTop(0); 133 | } -------------------------------------------------------------------------------- /application/player/index.css: -------------------------------------------------------------------------------- 1 | /* First of all */ 2 | * { 3 | box-sizing: border-box; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | /* Tab */ 9 | .tab { 10 | width: 100%; 11 | height: 30px; 12 | position: fixed; 13 | top: 150px; 14 | background-color: white; 15 | z-index: 2; 16 | } 17 | 18 | .tab li { 19 | float: left; 20 | list-style: none; 21 | margin: 7.5; 22 | font-size: 14px; 23 | position: relative; 24 | top: -3px; 25 | } 26 | 27 | .focus { 28 | border-bottom: 3px solid #d26585; 29 | } 30 | 31 | /* Item */ 32 | .items, 33 | .pages { 34 | position: absolute; 35 | width: 100%; 36 | height: calc(100% - 210px); 37 | overflow-x: hidden; 38 | overflow-y: auto; 39 | z-index: 1; 40 | top: 180px; 41 | background-color: white; 42 | } 43 | 44 | .item { 45 | position: relative; 46 | width: 100%; 47 | height: 60px; 48 | background-color: white; 49 | outline: none; 50 | } 51 | .pages .item { 52 | height: 24px; 53 | line-height: 24px; 54 | } 55 | 56 | .item:focus, 57 | .item.select { 58 | background-color: #d26585; 59 | color: white; 60 | } 61 | 62 | /* Item's inner */ 63 | /*video infos*/ 64 | .items #title { 65 | height: auto; 66 | padding: 4px; 67 | } 68 | 69 | .items #desc { 70 | height: 82px; 71 | padding: 4px; 72 | } 73 | 74 | .items #title #title { 75 | position: unset; 76 | top: 5px; 77 | height: auto; 78 | left: 10px; 79 | font-size: 14px; 80 | } 81 | 82 | .items #title #info { 83 | position: unset; 84 | bottom: 5px; 85 | left: 10px; 86 | height: auto; 87 | font-size: 12px; 88 | display: inline; 89 | } 90 | .items #title #info div { 91 | height: 12px; 92 | margin-right: 3px; 93 | display: inline; 94 | } 95 | 96 | .items #title #info div img { 97 | width: 12px; 98 | height: 12px; 99 | } 100 | 101 | .items #title:focus #info div img { 102 | filter: grayscale(100%) brightness(900%); 103 | } 104 | 105 | .items #title #info div a { 106 | position: relative; 107 | bottom: 2px; 108 | margin-left: 4px; 109 | } 110 | 111 | .items #sanlian { 112 | font-size: 10px; 113 | } 114 | 115 | .items #sanlian div { 116 | width: 30px; 117 | height: 60px; 118 | display: inline-block; 119 | margin-top: 10px; 120 | margin-left: calc(calc(100% - 90px) / 4); 121 | } 122 | .items #sanlian div img { 123 | width: 30px; 124 | height: 30px; 125 | } 126 | .items #sanlian:focus div img { 127 | filter: grayscale(100%) brightness(900%); 128 | } 129 | .items #sanlian div a { 130 | display: block; 131 | } 132 | 133 | /* Player */ 134 | .video_normal { 135 | width: 240px; 136 | height: 150px; 137 | } 138 | 139 | .video_fullscreen { 140 | width: 320px; 141 | height: 240px; 142 | position: fixed; 143 | transform: rotate(90deg); 144 | top: 40px; 145 | left: -40px; 146 | } 147 | 148 | #palyercontainter > canvas.fullscreen { 149 | width: 320px; 150 | height: 198px; 151 | position: fixed !important; 152 | transform: rotate(90deg); 153 | top: 40px !important; 154 | left: -40px !important; 155 | } 156 | 157 | #player { 158 | background-color: black; 159 | z-index: 98; 160 | } 161 | /* Soft Keys */ 162 | #softkeys { 163 | position: fixed; 164 | bottom: 0; 165 | left: 0; 166 | width: 100%; 167 | height: 30px; 168 | background: #dadada; 169 | padding: 3px 5px; 170 | z-index: 10; 171 | } 172 | 173 | #softkeys > * { 174 | display: inline-block; 175 | width: 72px; 176 | padding: 0 5px; 177 | } 178 | 179 | #softkey-left, 180 | #softkey-right { 181 | font-weight: 400; 182 | font-size: 14px; 183 | color: #323232; 184 | } 185 | 186 | #softkey-right { 187 | text-align: right; 188 | } 189 | 190 | #softkey-center { 191 | font-weight: 600; 192 | font-size: 16px; 193 | width: 76px; 194 | color: #323232; 195 | text-align: center; 196 | } 197 | 198 | .commenthead { 199 | float: left; 200 | position: relative; 201 | width: 100%; 202 | height: 42px; 203 | outline: none; 204 | } 205 | .itemcomment { 206 | float: left; 207 | position: relative; 208 | padding: 5px 0; 209 | width: 100%; 210 | background-color: white; 211 | outline: none; 212 | font-size: 14px; 213 | } 214 | .comment { 215 | float: left; 216 | position: relative; 217 | padding: 0 4px; 218 | width: 100%; 219 | outline: none; 220 | max-height: 60px; 221 | } 222 | .itemcomment:focus { 223 | background-color: #d26585; 224 | color: white; 225 | } 226 | .left_img { 227 | width: 36px; 228 | height: 100%; 229 | margin: 0 5px; 230 | float: left; 231 | } 232 | 233 | .user-info { 234 | margin-left: 50px; 235 | } 236 | 237 | canvas { 238 | top: 0 !important; 239 | left: 0 !important; 240 | z-index: 99 !important; 241 | position: fixed !important; 242 | } 243 | -------------------------------------------------------------------------------- /application/music/index.js: -------------------------------------------------------------------------------- 1 | let tab_location = 0, data = null; 2 | $(function () { 3 | loadData(); 4 | document.activeElement.addEventListener('keydown', handleKeydown); 5 | }); 6 | function loadData() { 7 | var url = 'https://api.bilibili.com/audio/music-service-c/firstpage'; 8 | var result = $.getApi(url); 9 | if (result.code == 0) { 10 | data = result.data; 11 | loadView(); 12 | } 13 | else { 14 | alert(result.message); 15 | } 16 | } 17 | function selectItem() { 18 | const items = document.querySelectorAll('.item'); 19 | const targetElement = items[current]; 20 | if (targetElement) { 21 | switch (tab_location) { 22 | case 0: 23 | case 1: 24 | case 3: { 25 | var id = $(targetElement).attr('data-id'); 26 | window.location.href = '../musicmenu/index.html?id=' + id; 27 | break; 28 | } 29 | case 2: { 30 | var id = $(targetElement).attr('data-id'); 31 | window.location.href = '../songinfo/index.html?id=' + id; 32 | break; 33 | } 34 | } 35 | } 36 | } 37 | function loadView() { 38 | $('.items').empty(); 39 | switch (tab_location) { 40 | case 0: { 41 | for (var index = 0; index < data.common.length; index++) { 42 | var item = data.common[index]; 43 | var html = '

' + item.title + '

播放:' 44 | + item.playNum + '

'; 45 | $('.items').append(html); 46 | } 47 | break; 48 | } 49 | case 1: { 50 | for (var index = 0; index < data.pmenu.length; index++) { 51 | var item = data.pmenu[index]; 52 | var html = '

' + item.title + '

播放:' 53 | + item.playNum + '

'; 54 | $('.items').append(html); 55 | } 56 | break; 57 | } 58 | case 2: { 59 | for (var index = 0; index < data.hitSongs.length; index++) { 60 | var item = data.hitSongs[index]; 61 | var html = '

' + item.title + '

播放:' + item.play_num + '

'; 62 | $('.items').append(html); 63 | } 64 | break; 65 | } 66 | case 3: { 67 | for (var index = 0; index < data.categories.length; index++) { 68 | var item = data.categories[index]; 69 | var html = '

' + item.title + '

播放:' + item.playNum + '

'; 70 | $('.items').append(html); 71 | } 72 | break; 73 | } 74 | } 75 | } 76 | function handleKeydown(e) { 77 | $.clearEvent(e); 78 | switch (e.key) { 79 | case 'ArrowUp': 80 | nav(-1); 81 | break; 82 | case 'ArrowDown': 83 | nav(1); 84 | break; 85 | case 'ArrowRight': 86 | tab(1); 87 | break; 88 | case 'ArrowLeft': 89 | tab(-1); 90 | break; 91 | case 'Enter': 92 | break; 93 | case 'Q': 94 | case 'SoftLeft': 95 | selectItem(); 96 | break; 97 | case 'E': 98 | case 'Backspace': 99 | case 'SoftRight': 100 | window.location.href = '../index.html'; 101 | break; 102 | } 103 | } 104 | var current = -1; 105 | function nav(move) { 106 | var next = current + move; 107 | const items = document.querySelectorAll('.item'); 108 | if (next >= items.length) 109 | next = items.length - 1; 110 | else if (next < 0) 111 | next = 0; 112 | const targetElement = items[next]; 113 | if (targetElement) { 114 | current = next; 115 | targetElement.focus(); 116 | $('.item').removeClass('select'); 117 | $(targetElement).addClass('select'); 118 | } 119 | } 120 | function tab(move) { 121 | var currentIndex = parseInt($('.focus').attr('tabIndex')); 122 | var next = currentIndex + move; 123 | if (next > 4) 124 | next = 0; 125 | if (next < 0) 126 | next = 4; 127 | var items = document.querySelectorAll('li'); 128 | var targetElement = items[next]; 129 | if (targetElement) { 130 | $('.focus').attr("class", ""); 131 | targetElement.className = "focus"; 132 | tab_location = next; 133 | loadView(); 134 | } 135 | } -------------------------------------------------------------------------------- /application/bangmi/index.js: -------------------------------------------------------------------------------- 1 | var page = 1, type = 0; 2 | var data = null; 3 | var tab_location = 1;//设置header位置 4 | $(function () { 5 | type = $.getQueryVar('type'); 6 | type = parseInt(type); 7 | myFollow(); 8 | homeData(); 9 | document.activeElement.addEventListener('keydown', handleKeydown); 10 | }); 11 | function load() { 12 | $('.items').empty(); 13 | switch (tab_location) { 14 | case 0: { 15 | myFollow(); 16 | break; 17 | } 18 | case 1: { 19 | var arr = data.today; 20 | if (data != null && arr != null) { 21 | for (var index = 0; index < arr.length; index++) { 22 | var html = '

' + arr[index].title + '

' 23 | + arr[index].pub_index + '

'; 24 | $('.items').append(html); 25 | } 26 | } 27 | break; 28 | } 29 | case 2: { 30 | var arr = data.ranks; 31 | if (data != null && arr != null) { 32 | for (var index = 0; index < arr.length; index++) { 33 | var html = '

' + arr[index].title + '

' 34 | + arr[index].index_show + '

'; 35 | $('.items').append(html); 36 | } 37 | } 38 | break; 39 | } 40 | case 3: { 41 | var arr = data.hots; 42 | if (data != null && arr != null) { 43 | for (var index = 0; index < arr.length; index++) { 44 | var html = '

' + arr[index].title + '

' 45 | + arr[index].index_show + '

'; 46 | $('.items').append(html); 47 | } 48 | } 49 | break; 50 | } 51 | } 52 | } 53 | function homeData() { 54 | var url = type == 0 ? 'http://biliapi.iliili.cn/api/anime/bangumi' : 'http://biliapi.iliili.cn/api/anime/guochuang'; 55 | $.get(url, function (result) { 56 | if (result.code == 0) { 57 | data = result.data; 58 | } 59 | }); 60 | } 61 | function myFollow() { 62 | var url = 'http://bangumi.bilibili.com/api/get_concerned_season?page=' + page + '&pagesize=9'; 63 | var result = $.getApi(url); 64 | if (result.code == 0) { 65 | var arr = result.result; 66 | if (arr != null) { 67 | for (var index = 0; index < arr.length; index++) { 68 | var html = '

' + arr[index].title + '

' 69 | + arr[index].update_pattern + '

'; 70 | $('.items').append(html); 71 | } 72 | } 73 | } 74 | } 75 | function handleKeydown(e) { 76 | $.clearEvent(e); 77 | switch (e.key) { 78 | case 'ArrowRight': 79 | tab(1); 80 | break; 81 | case 'ArrowLeft': 82 | tab(-1); 83 | break; 84 | case 'ArrowUp': 85 | nav(-1); 86 | break; 87 | case 'ArrowDown': 88 | nav(1); 89 | break; 90 | case 'Q': 91 | case 'SoftLeft': { 92 | const items = document.querySelectorAll('.item'); 93 | const targetElement = items[current]; 94 | var id = $(targetElement).attr('data-id'); 95 | window.location.href = '../bandetail/index.html?id=' + id; 96 | break; 97 | } 98 | case 'E': 99 | case 'Backspace': 100 | case 'SoftRight': 101 | window.location.href = '../index.html'; 102 | break; 103 | } 104 | } 105 | function tab(move) { 106 | var currentIndex = parseInt($('.focus').attr('tabIndex')); //获取目前带有focus的元素的tabIndex 107 | var next = currentIndex + move; //设置移动位置 108 | if (next > 4) { 109 | next = 0; 110 | } 111 | if (next < 0) { 112 | next = 4; 113 | } 114 | var items = document.querySelectorAll('li'); //遍历所有的li元素 115 | var targetElement = items[next]; //将位置与遍历结果对应 116 | if (targetElement == undefined) { //如果没有可供选择的目标 117 | return; //中止函数 118 | } 119 | $('.focus').attr("class", ""); //清除原有效果 120 | targetElement.className = "focus"; //设置新效果 121 | tab_location = next; 122 | load(); 123 | } 124 | var current = 0; 125 | function nav(move) { 126 | var next = current + move; 127 | const items = document.querySelectorAll('.item'); 128 | if (next >= items.length) { 129 | next = items.length - 1; 130 | } 131 | else if (next < 0) { 132 | next = 0; 133 | } 134 | const targetElement = items[next]; 135 | if (targetElement) { 136 | current = next; 137 | targetElement.focus(); 138 | $('.item').removeClass('select'); 139 | $(targetElement).addClass('select'); 140 | } 141 | } -------------------------------------------------------------------------------- /application/collection/index.js: -------------------------------------------------------------------------------- 1 | let page = 1; 2 | let userId = 0; 3 | let isOpen = false; 4 | let fid = 0; 5 | 6 | $(function () { 7 | userId = $.getData('mid'); 8 | var url = 'https://api.bilibili.com/medialist/gateway/base/created?channel=bilih5&pn=1&ps=20&type=2&up_mid=' + userId; 9 | var result = $.getApi(url); 10 | if (result.code == 0) { 11 | try { 12 | var arr = result.data.list, options = ''; 13 | for (var index = 0; index < arr.length; index++) { 14 | var item = arr[index]; 15 | options += ''; 16 | } 17 | fid = arr[0].fid; 18 | loadBox(); 19 | $('#menucontainer').append(options); 20 | } 21 | catch (e) { 22 | console.log(e); 23 | } 24 | } 25 | else { 26 | alert('获取收藏夹失败!'); 27 | } 28 | document.activeElement.addEventListener('keydown', handleKeydown); 29 | }); 30 | 31 | function handleKeydown(e) { 32 | $.clearEvent(e); 33 | switch (e.key) { 34 | case 'ArrowUp': 35 | nav(-1); 36 | break; 37 | case 'ArrowDown': 38 | nav(1); 39 | break; 40 | case 'Q': 41 | case 'SoftLeft': 42 | if (isOpen) { 43 | const item = document.querySelectorAll('.menuitem')[menu]; 44 | if (typeof item != 'undefined') { 45 | page = 1; 46 | fid = $(item).attr('value'); 47 | loadBox(); 48 | } 49 | } 50 | else { 51 | const item = document.querySelectorAll('.item')[current]; 52 | if (typeof item != 'undefined') { 53 | var aid = $(item).attr('data-aid'), cid = $(item).attr('data-cid'); 54 | window.location.href = '../player/index.html?aid=' + aid + '&cid=' + cid + '&type=collection'; 55 | } 56 | } 57 | showhideMenu(); 58 | break; 59 | case 'Backspace': 60 | window.location.href = '../user/index.html?mid=' + userId; 61 | break; 62 | case 'Enter': 63 | if (!isOpen) { 64 | page++; 65 | loadBox(); 66 | } 67 | break; 68 | case 'E': 69 | case 'SoftRight': 70 | showhideMenu(); 71 | break; 72 | } 73 | } 74 | 75 | function loadBox() { 76 | var url = 'http://api.bilibili.com/x/v2/fav/video?pn=' + page + '&ps=20&tid=0&fid=' + fid + '&vmid=' + userId + '&order=ftime'; 77 | var result = $.getApi(url); 78 | if (page == 1) 79 | $('#container').empty(); 80 | if (result.code == 0) { 81 | var arr = result.data.archives; 82 | for (var index = 0; index < arr.length; index++) { 83 | var item = arr[index]; 84 | var name = ''; 85 | if (item.owner != null) 86 | name = item.owner.name; 87 | $('#container').append("
" + item.title + "
UP
" + name + "
"); 89 | } 90 | } 91 | else { 92 | alert('获取收藏夹内容失败!' + result.message); 93 | } 94 | } 95 | 96 | function showhideMenu() { 97 | if (isOpen) { 98 | $("#menu").hide(); 99 | softkey("登录", "主页", "选项"); 100 | isOpen = false; 101 | } 102 | else { 103 | $("#menu").show(); 104 | var items = document.querySelectorAll('.menuitem'); 105 | items[0].focus(); 106 | softkey("选择", "", "返回"); 107 | isOpen = true; 108 | } 109 | } 110 | 111 | function softkey(left, center, right) { 112 | $('#softkey-left').text(left); 113 | $('#softkey-center').text(center); 114 | $('#softkey-right').text(right); 115 | } 116 | 117 | var current = -1, menu = 0; 118 | function nav(move) { 119 | if (!isOpen) { 120 | var next = current + move; 121 | const items = document.querySelectorAll('.item'); 122 | if (next >= items.length) { 123 | next = items.length - 1; 124 | } 125 | else if (next < 0) { 126 | next = 0; 127 | } 128 | const targetElement = items[next]; 129 | if (targetElement) { 130 | current = next; 131 | targetElement.focus(); 132 | $('.item').removeClass('select'); 133 | $(targetElement).addClass('select'); 134 | } 135 | } 136 | else { 137 | var next = menu + move; 138 | const items = document.querySelectorAll('.menuitem'); 139 | if (next >= items.length) { 140 | next = items.length - 1; 141 | } 142 | else if (next < 0) { 143 | next = 0; 144 | } 145 | const targetElement = items[next]; 146 | if (targetElement) { 147 | menu = next; 148 | targetElement.focus(); 149 | $('.menuitem').removeClass('select'); 150 | $(targetElement).addClass('select'); 151 | } 152 | 153 | } 154 | } -------------------------------------------------------------------------------- /application/danmaku.js: -------------------------------------------------------------------------------- 1 | window.danmaku = null; 2 | $.extend({ 3 | showDanmaku: function (text, time, color) { 4 | if (typeof color == 'undefined' || color == '') 5 | color = '#ffffff'; 6 | var comment = { 7 | text: text, 8 | style: { 9 | fontSize: '12px', 10 | color: color 11 | } 12 | }; 13 | if (typeof time != 'undefined' && time != '' && time > 0) 14 | comment.time = time; 15 | danmaku.emit(comment); 16 | }, 17 | sendDanmaku: function (aid, cid, mid, p, color, msg) { 18 | var json = null; 19 | var ts = $.getTs(); 20 | var access_token = this.getData('access_token'); 21 | var url = 'https://api.bilibili.com/x/v2/dm/post?access_key=' + access_token + '&aid=' + aid + '&appkey=' + android.key + '&build=' + build + '&mobi_app=android&oid=' + cid + 22 | '&platform=android&ts=' + ts; 23 | url += "&sign=" + $.getSign(url); 24 | var content = 'pool=0&rnd=' + ts + '&oid=' + cid + '&fontsize=25&msg=' + encodeURIComponent(msg) + '&mode=' + mid + '&progress=' + p + '&color=' + color + 25 | '&plat=2&screen_state=0&from=861&type=1'; 26 | $.ajax({ 27 | url: url, 28 | data: content, 29 | type: 'post', 30 | async: false, 31 | headers: { 32 | 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36' 33 | }, 34 | success: function (data) { 35 | json = data; 36 | } 37 | }); 38 | return json; 39 | }, 40 | sendLiveDanmaku: function (rid, msg) { 41 | var json = null; 42 | try { 43 | var ts = $.getTs(); 44 | var mid = $.getQueryVar('mid'); 45 | var access_token = this.getData('access_token'); 46 | var content = 'cid=' + rid + '&mid=' + mid + '&msg=' + msg + '&rnd=' + ts + '&mode=1&pool=0&type=json&color=16777215&fontsize=25&playTime=0.0'; 47 | var url = 'https://api.live.bilibili.com/api/sendmsg?access_key=' + access_token + '&actionKey=appkey&appkey=' + android.key + '&build=' + build + '&device=android&mobi_app=android&platform=android&ts=' + ts; 48 | url += "&sign=" + $.getSign(url); 49 | $.ajax({ 50 | url: url, 51 | data: content, 52 | type: 'post', 53 | async: false, 54 | headers: { 55 | 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36' 56 | }, 57 | success: function (data) { 58 | json = data; 59 | } 60 | }); 61 | } 62 | catch (e) { 63 | console.log(e); 64 | } 65 | return json; 66 | }, 67 | sendComment: function (aid, text) { 68 | var json = null; 69 | try { 70 | var ts = $.getTs(); 71 | var access_token = this.getData('access_token'); 72 | var url = "https://api.bilibili.com/x/v2/reply/add"; 73 | var content = "access_key=" + access_token + "&appkey=" + android.key + "&platform=android&type=1&oid=" + aid + "&ts=" + ts + "&message=" + text; 74 | content += "&sign=" + $.getSign(content); 75 | $.ajax({ 76 | url: url, 77 | data: content, 78 | type: 'post', 79 | async: false, 80 | headers: { 81 | 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36' 82 | }, 83 | success: function (data) { 84 | json = data; 85 | } 86 | }); 87 | } 88 | catch (e) { 89 | console.log(e); 90 | } 91 | return json; 92 | }, 93 | getDanmaku: function (rootElementId, elementId, cid) { 94 | try { 95 | var url = 'https://api.bilibili.com/x/v1/dm/list.so?oid=' + cid; 96 | var result = $.getWeb(url); 97 | var nodes = result.getElementsByTagName('d'); 98 | var task = function () { 99 | var comments = []; 100 | for (var idx = 0; idx < nodes.length; idx++) { 101 | try { 102 | var content = nodes[idx].textContent; 103 | var attributes = nodes[idx].attributes[0].nodeValue.split(','); 104 | var mode = 'rtl', time = parseFloat(attributes[0]); 105 | switch (attributes[1]) { 106 | case '4': 107 | mode = 'bottom'; 108 | break; 109 | case '5': 110 | mode = 'top'; 111 | break; 112 | } 113 | comments.push({ 114 | text: content, 115 | mode: mode, 116 | time: time, 117 | style: { 118 | font: '12px', 119 | fillStyle: '#fff' 120 | } 121 | }); 122 | } 123 | catch (e) { 124 | console.log(e); 125 | } 126 | } 127 | window.danmaku = new Danmaku({ 128 | container: document.getElementById(rootElementId), 129 | media: document.getElementById(elementId), 130 | engine: 'canvas', 131 | comments: comments, 132 | speed: 80 133 | }); 134 | 135 | }; 136 | setTimeout(task, 60); 137 | } 138 | catch (e) { 139 | console.log(e); 140 | } 141 | } 142 | }); -------------------------------------------------------------------------------- /application/lib/danmaku.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Danmaku=e()}(this,(function(){"use strict";var t=function(){for(var t=["oTransform","msTransform","mozTransform","webkitTransform","transform"],e=document.createElement("div").style,i=0;i0&&a!==1/0?Math.ceil(a):1*!!h.strokeStyle,r.font=h.font,t.width=t.width||Math.max(1,Math.ceil(r.measureText(t.text).width)+2*a),t.height=t.height||Math.ceil(function(t,e){if(n[t])return n[t];var i=12,s=t.match(/(\d+(?:\.\d+)?)(px|%|em|rem)(?:\s*\/\s*(\d+(?:\.\d+)?)(px|%|em|rem)?)?/);if(s){var r=1*s[1]||10,h=s[2],a=1*s[3]||1.2,o=s[4];"%"===h&&(r*=e.container/100),"em"===h&&(r*=e.container),"rem"===h&&(r*=e.root),"px"===o&&(i=a),"%"===o&&(i=r*a/100),"em"===o&&(i=r*a),"rem"===o&&(i=e.root*a),void 0===o&&(i=r*a)}return n[t]=i,i}(h.font,e))+2*a,s.width=t.width,s.height=t.height,h)r[o]=h[o];var d=0;switch(h.textBaseline){case"top":case"hanging":d=a;break;case"middle":d=t.height>>1;break;default:d=t.height-a}return h.strokeStyle&&r.strokeText(t.text,a,d),r.fillText(t.text,a,d),s}function r(t){return 1*window.getComputedStyle(t,null).getPropertyValue("font-size").match(/(.+)px/)[1]}var h={name:"canvas",init:function(t){var e=document.createElement("canvas");return e.context=e.getContext("2d"),e._fontSize={root:r(document.getElementsByTagName("html")[0]),container:r(t)},e},clear:function(t,e){t.context.clearRect(0,0,t.width,t.height);for(var i=0;ir)return!0;var h=e._.duration+t.time-i,a=e._.stage.width+s.width,o=e.media?s.time:s._utc,d=a*(i-o)*n/e._.duration,u=e._.stage.width-d;return h>e._.duration*u/(e._.stage.width+s.width)}for(var r=this._.space[t.mode],h=0,a=0,o=1;o=u){a=o;break}s(d,t)&&(h=o)}var m=r[h].range,c={range:m+t.height,time:this.media?t.time:t._utc,width:t.width,height:t.height};return r.splice(h+1,a-h-1,c),"bottom"===t.mode?this._.stage.height-t.height-m%this._.stage.height:m%(this._.stage.height-t.height)}var o=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||function(t){return setTimeout(t,50/3)},d=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||clearTimeout;function u(t,e,i){for(var n=0,s=0,r=t.length;s=t[n=s+r>>1][e]?s=n:r=n;return t[s]&&i=0;u--)o=this._.runningList[u],r-(d=this.media?o.time:o._utc)>this._.duration&&(n(this._.stage,o),this._.runningList.splice(u,1));for(var m=[];this._.position=r));)r-d>this._.duration||(this.media&&(o._utc=s-(this.media.currentTime-o.time)),m.push(o)),++this._.position;for(e(this._.stage,m),u=0;u>1),this._.runningList.push(o);for(u=0;u

' + content + '

'; 23 | $('.items').prepend(html); 24 | 25 | const items = document.querySelectorAll('.itemcomment'); 26 | const targetElement = items[0]; 27 | if (targetElement) { 28 | targetElement.focus(); 29 | targetElement.scrollIntoView(true); 30 | $('.items').scrollTop(0); 31 | } 32 | break; 33 | } 34 | } 35 | } 36 | 37 | function makeLive(room_id) { 38 | $.getJSON('https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id=' + room_id + 39 | '&qn=80&platform=web&protocol=0,1&format=0,2&codec=0,1&ptype=8', function (result) { 40 | if (result.code != 0) { 41 | alert('获取直播地址失败!'); 42 | return; 43 | } 44 | if (result.data.playurl_info) { 45 | var data = result.data.playurl_info.playurl.stream[0].format[0].codec[0]; 46 | var url = data.url_info[0].host + data.base_url + data.url_info[0].extra; 47 | try { 48 | player = flvjs.createPlayer({ 49 | type: 'flv', 50 | isLive: true, 51 | url: url 52 | }); 53 | player.attachMediaElement(document.getElementById('player')); 54 | player.load(); 55 | player.play(); 56 | } 57 | catch (e) { 58 | console.log(e); 59 | alert('初始化播放器失败!'); 60 | } 61 | } 62 | else { 63 | alert("直播不在进行中!"); 64 | } 65 | }); 66 | } 67 | 68 | function setData(name, sign, title) { 69 | $('.items').empty(); 70 | $('.items').append("

主播名称:" + name + "

"); 71 | $('.items').append("

直播间标题:" + title + "

") 72 | $('.items').append("

直播签名:" + sign + "

"); 73 | if (document.querySelectorAll('.item')[0]) { 74 | document.querySelectorAll('.item')[0].focus() 75 | } 76 | } 77 | 78 | function tab(move) { 79 | const currentIndex = parseInt($('.focus').attr('tabIndex')); 80 | var next = currentIndex + move; 81 | if (next > 1) { 82 | next = 0; 83 | } 84 | else if (next < 0) { 85 | next = 1; 86 | } 87 | const items = document.querySelectorAll('li'); 88 | const targetElement = items[next]; 89 | if (targetElement) { 90 | $('.focus').attr("class", ""); 91 | targetElement.className = "focus"; 92 | tab_location = next; 93 | if (tab_location == 0) { 94 | $('#softkey-left').text('全屏'); 95 | $('#softkey-right').text('重新加载'); 96 | } 97 | else if (tab_location == 1) { 98 | $('#softkey-left').text('刷新弹幕'); 99 | $('#softkey-right').text('发送弹幕'); 100 | } 101 | load(); 102 | } 103 | } 104 | var commentIndex = 0; 105 | function appendComments(item, tabIndex) { 106 | commentIndex = tabIndex; 107 | var content = item.text; 108 | var uname = item.nickname; 109 | var ctime = item.timeline; 110 | $('.items').append('

' + content + '

') 112 | } 113 | 114 | function getComments(page) { 115 | if (page) { } 116 | else { 117 | $('.items').empty(); 118 | $('.items').append('正在加载…'); 119 | commentpage = 1; 120 | page = 1; 121 | } 122 | url = 'https://api.live.bilibili.com/ajax/msg?roomid=' + thisRoomId; 123 | $.getJSON(url, function (result) { 124 | if (result.data.room) { 125 | $('.items').empty(); 126 | $.each(result.data.room.reverse(), function (r, item) { 127 | appendComments(item, r); 128 | }); 129 | } 130 | else { 131 | alert("没有获取到更多弹幕!"); 132 | return; 133 | } 134 | if (document.querySelectorAll('.itemcomment')[0]) { 135 | document.querySelectorAll('.itemcomment')[0].focus() 136 | } 137 | }).fail(function (jqXHR, status, error) { 138 | alert(error + ",请求可能被拦截"); 139 | }); 140 | } 141 | 142 | function load() { 143 | switch (tab_location) { 144 | case 0: 145 | getLiveRoomNumer($.getQueryVar('uid')) 146 | var video = document.getElementById("player"); 147 | if (video.paused == true) { 148 | $('#softkey-center').text('播放'); 149 | } 150 | else { 151 | $('#softkey-center').text('暂停'); 152 | } 153 | break; 154 | case 1: 155 | getComments(); 156 | $('#softkey-center').text("查看") 157 | break; 158 | } 159 | } 160 | 161 | function nav(move) { 162 | if (tab_location === 0) { 163 | const currentIndex = document.activeElement.tabIndex; 164 | var next = currentIndex + move; 165 | const items = document.querySelectorAll('.item'); 166 | if (next >= items.length) { 167 | next = items.length - 1; 168 | } 169 | else if (next < 0) { 170 | next = 0; 171 | } 172 | const targetElement = items[next]; 173 | if (targetElement) { 174 | targetElement.focus(); 175 | targetElement.scrollIntoView(true); 176 | } 177 | if (next == 0) { 178 | $('.items').scrollTop(0); 179 | } 180 | } 181 | else if (tab_location === 1) { 182 | const currentIndex = document.activeElement.tabIndex; 183 | var next = currentIndex + move; 184 | const items = document.querySelectorAll('.itemcomment'); 185 | if (next >= items.length) { 186 | next = items.length - 1; 187 | } 188 | else if (next < 0) { 189 | next = 0; 190 | } 191 | const targetElement = items[next]; 192 | if (targetElement) { 193 | targetElement.focus(); 194 | targetElement.scrollIntoView(true); 195 | } 196 | if (next == 0) { 197 | $('.items').scrollTop(0); 198 | } 199 | } 200 | } 201 | 202 | function getLiveRoomNumer(uid) { 203 | var id, link ='https://api.live.bilibili.com/xlive/web-room/v1/index/getRoomBaseInfo?uids='+uid+'&req_biz=video';//'https://api.bilibili.com/x/space/acc/info?mid=' + uid; 204 | $.ajax({ 205 | url: link, 206 | async: false, 207 | success: function (result) { 208 | id = result.data.by_uids[uid].room_id.toString(); 209 | var name = result.data.name; 210 | var sign = result.data.sign; 211 | var title = result.data.live_room.title; 212 | setData(name, sign, title); 213 | } 214 | }); 215 | return id; 216 | } 217 | 218 | function fullscreen(value) { 219 | if (value == false) { 220 | document.exitFullscreen(); 221 | $('#player').attr('class', 'player'); 222 | } 223 | else if (value == true) { 224 | document.documentElement.requestFullscreen(); 225 | $('#player').attr('class', 'player_fullscreen'); 226 | } 227 | } 228 | 229 | function enter() { 230 | if ($('#softkey-center').text() === '查看') { 231 | var items = document.querySelectorAll('.comment'); 232 | var targetElement = items[document.activeElement.tabIndex]; 233 | if (targetElement) 234 | alert($(targetElement).text()); 235 | } 236 | else { 237 | if (document.getElementById('player').paused == true) { 238 | document.getElementById('player').play(); 239 | $('#softkey-center').text('暂停'); 240 | } 241 | else { 242 | document.getElementById('player').pause(); 243 | $('#softkey-center').text('播放'); 244 | } 245 | } 246 | } 247 | 248 | function handleKeydown(e) { 249 | $.clearEvent(e); 250 | switch (e.key) { 251 | case 'ArrowUp': 252 | nav(-1); 253 | break; 254 | case 'ArrowDown': 255 | nav(1); 256 | break; 257 | case 'ArrowRight': 258 | tab(1); 259 | break; 260 | case 'ArrowLeft': 261 | tab(-1); 262 | break; 263 | case 'Enter': 264 | enter(); 265 | break; 266 | case 'Backspace': 267 | window.location.href = '../index.html?ref=' + $.getQueryVar('ref') 268 | break; 269 | case 'Q': 270 | case 'SoftLeft': 271 | if (tab_location === 0) { 272 | var v = $('#player').attr('class') == 'player'; 273 | fullscreen(v); 274 | } 275 | else if (tab_location === 1) { 276 | getComments(); 277 | } 278 | break; 279 | case 'E': 280 | case 'SoftRight': 281 | if (tab_location === 0) { 282 | location.reload(); 283 | } 284 | else { 285 | var text = prompt("请输入弹幕内容", ""); 286 | if (text != '') { 287 | var result = $.sendLiveDanmaku(thisRoomId, text); 288 | if (result.code != 0) 289 | alert('发送弹幕失败!' + result.message); 290 | } 291 | } 292 | break; 293 | case '2': 294 | navigator.volumeManager.requestUp(); 295 | break; 296 | case '8': 297 | navigator.volumeManager.requestDown(); 298 | break; 299 | } 300 | } -------------------------------------------------------------------------------- /application/app.js: -------------------------------------------------------------------------------- 1 | const build = '5442100'; 2 | // const android = { 3 | // key: '1d8b6e7d45233436', 4 | // secret: '560c52ccd288fed045859ed18bffd973' 5 | // }; 6 | // const web = { 7 | // key: '84956560bc028eb7', 8 | // secret: '94aba54af9065f71de72f5508f1cd42e' 9 | // }; 10 | const tv = { 11 | key: '4409e2ce8ffd12b8', 12 | secret: '59b43e04ad6965f34319062b478f83dd' 13 | }; 14 | //这里因为使用了tv的登录协议,所以也要改成tv才行 15 | const android = tv; 16 | const web = tv; 17 | 18 | $.extend({ 19 | Async: function () { 20 | var task = new Promise(function (resolve) { 21 | resolve(); 22 | }); 23 | return task; 24 | }, 25 | getById: function (id) { 26 | return document.getElementById(id); 27 | }, 28 | clearEvent: function (e) { 29 | try { 30 | var key = e.key; 31 | if (key != "EndCall" && key.toLowerCase().indexOf('arrow') == -1) 32 | e.preventDefault(); 33 | } 34 | catch (e) { 35 | console.log(e); 36 | } 37 | }, 38 | initApi: function () { 39 | $.ajaxSettings.xhr = function () { 40 | try { 41 | return new XMLHttpRequest({ mozSystem: true }); 42 | } catch (e) { } 43 | }; 44 | }, 45 | postApi: function (url, content, keyValue) { 46 | var json = null; 47 | if (keyValue == undefined || keyValue == null || typeof keyValue == 'undefined') 48 | keyValue = android; 49 | var access_token = this.getData('access_token'); 50 | content += '&access_key=' + access_token + '&appkey=' + keyValue.key + '&mobi_app=android&platform=android&ts=' + this.getTs(); 51 | content += "&sign=" + this.getSign(content, keyValue.secret); 52 | $.ajax({ 53 | url: url, 54 | data: content, 55 | type: 'post', 56 | async: false, 57 | beforeSend: function (request) { 58 | $.showLoading(); 59 | request.setRequestHeader("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36") 60 | }, 61 | success: function (data) { 62 | json = data; 63 | }, 64 | error: function (xhr) { 65 | json = xhr.responseJSON; 66 | }, 67 | complete: function () { 68 | $.hideLoading(); 69 | } 70 | }); 71 | return json; 72 | }, 73 | postApiAsync: function (url, content, callback, keyValue) { 74 | if (keyValue == undefined || keyValue == null || typeof keyValue == 'undefined') 75 | keyValue = android; 76 | var access_token = this.getData('access_token'); 77 | content += '&access_key=' + access_token + '&appkey=' + keyValue.key + '&mobi_app=android&platform=android&ts=' + this.getTs(); 78 | content += "&sign=" + this.getSign(content, keyValue.secret); 79 | $.ajax({ 80 | url: url, 81 | data: content, 82 | type: 'post', 83 | async: true, 84 | beforeSend: function (request) { 85 | $.showLoading(); 86 | request.setRequestHeader("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36") 87 | }, 88 | success: function (data) { 89 | callback(data); 90 | }, 91 | error: function (xhr) { 92 | var data = xhr.responseJSON; 93 | callback(data); 94 | }, 95 | complete: function () { 96 | $.hideLoading(); 97 | } 98 | }); 99 | }, 100 | getApi: function (url, keyValue) { 101 | var json = null; 102 | if (keyValue == undefined || keyValue == null || typeof keyValue == 'undefined') 103 | keyValue = android; 104 | var access_token = this.getData('access_token'); 105 | if (url.indexOf('?') > -1) 106 | url += '&access_key=' + access_token + '&appkey=' + keyValue.key + '&platform=android&build=' + build + '&mobi_app=android&ts=' + this.getTs(); 107 | else 108 | url += '?access_key=' + access_token + '&appkey=' + keyValue.key + '&platform=android&build=' + build + '&mobi_app=android&ts=' + this.getTs(); 109 | url += "&sign=" + this.getSign(url, keyValue.secret); 110 | $.ajax({ 111 | url: url, 112 | type: "get", 113 | async: false, 114 | beforeSend: function (request) { 115 | $.showLoading(); 116 | request.setRequestHeader("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36") 117 | }, 118 | success: function (data) { 119 | json = data; 120 | }, 121 | error: function (xhr) { 122 | json = xhr.responseJSON; 123 | }, 124 | complete: function () { 125 | $.hideLoading(); 126 | } 127 | }); 128 | return json; 129 | }, 130 | getWeb: function (url) { 131 | var json = null; 132 | $.ajax({ 133 | url: url, 134 | type: "get", 135 | async: false, 136 | beforeSend: function (request) { 137 | $.showLoading(); 138 | request.setRequestHeader("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36") 139 | }, 140 | success: function (data) { 141 | json = data; 142 | }, 143 | error: function (xhr) { 144 | json = xhr.responseJSON; 145 | }, 146 | complete: function () { 147 | $.hideLoading(); 148 | } 149 | }); 150 | return json; 151 | }, 152 | getApiAsync: function (url, callback, keyValue) { 153 | if (keyValue == undefined || keyValue == null || typeof keyValue == 'undefined') 154 | keyValue = android; 155 | var access_token = this.getData('access_token'); 156 | url += '&access_key=' + access_token + '&appkey=' + keyValue.key + '&platform=android&build=' + build + '&mobi_app=android&ts=' + this.getTs(); 157 | url += "&sign=" + this.getSign(url, keyValue.secret); 158 | $.ajax({ 159 | url: url, 160 | type: "get", 161 | async: true, 162 | beforeSend: function (request) { 163 | $.showLoading(); 164 | request.setRequestHeader("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36") 165 | }, 166 | success: function (data) { 167 | callback(data); 168 | }, 169 | error: function (xhr) { 170 | var data = xhr.responseJSON; 171 | callback(data); 172 | }, 173 | complete: function () { 174 | $.hideLoading(); 175 | } 176 | }); 177 | }, 178 | getData: function (key) { 179 | try { 180 | var value = localStorage.getItem(key); 181 | if (value == undefined || typeof value == 'undefined' || value == null) 182 | value = ''; 183 | return value; 184 | } 185 | catch (e) { 186 | console.log(e); 187 | } 188 | return ''; 189 | }, 190 | setData: function (key, value) { 191 | try { 192 | localStorage.setItem(key, value); 193 | } 194 | catch (e) { 195 | console.log(e); 196 | } 197 | }, 198 | getSign: function (url, secret) { 199 | if (typeof secret == 'undefined') 200 | secret = android.Secret; 201 | var str = url.substring(url.indexOf("?", 4) + 1); 202 | var list = str.split('&'); 203 | list.sort(); 204 | var stringBuilder = ''; 205 | for (var index = 0; index < list.length; index++) { 206 | stringBuilder += (stringBuilder.length > 0 ? '&' : ''); 207 | stringBuilder += list[index]; 208 | } 209 | stringBuilder += secret; 210 | var result = stringBuilder; 211 | result = md5(stringBuilder); 212 | return result.toLowerCase(); 213 | }, 214 | getTs: function () { 215 | var ts = new Date().getTime().toString(); 216 | if (ts.length > 10) 217 | ts = ts.substring(0, 10); 218 | return ts; 219 | }, 220 | //获取url传值 221 | getQueryVar: function (variable) { 222 | var query = window.location.search.substring(1); 223 | var vars = query.split("&"); 224 | console.log(vars) 225 | for (var i = 0; i < vars.length; i++) { 226 | var pair = vars[i].split("="); 227 | console.log(pair) 228 | if (pair[0] == variable) { return pair[1]; } 229 | } 230 | return (false); 231 | }, 232 | getKeyValue: function (value) { 233 | var result = null; 234 | if (value != null && typeof value == 'string') { 235 | if (value.indexOf(':') > -1) { 236 | var arr = value.split(':'); 237 | if (arr.length > 1) 238 | result = arr[1]; 239 | } 240 | else if (value.indexOf('=') > -1) { 241 | var arr = value.split('='); 242 | if (arr.length > 1) 243 | result = arr[1]; 244 | } 245 | } 246 | else if (value instanceof Array) { 247 | if (value.length > 0) { 248 | result = this.getKeyValue(value[0]); 249 | } 250 | } 251 | return result; 252 | }, 253 | toDateTimeString: function (timestamp) { 254 | var date = new Date(timestamp * 1000); 255 | var Y = date.getFullYear() + '-'; 256 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; 257 | var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '; 258 | var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'; 259 | var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'; 260 | var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); 261 | return Y + M + D + h + m + s; 262 | } 263 | }); 264 | 265 | $(function () { 266 | $.initApi(); 267 | }); -------------------------------------------------------------------------------- /application/dynamic/index.js: -------------------------------------------------------------------------------- 1 | let last_parm = '', userId = 0, self = false; 2 | let scrollHeight = 0; 3 | $(function () { 4 | userId = $.getQueryVar('mid'); 5 | if (userId === false) 6 | userId = $.getData('mid'); 7 | self = userId == $.getData('mid'); 8 | loadData(); 9 | document.activeElement.addEventListener('keydown', handleKeydown); 10 | }); 11 | function loadData() { 12 | if (self) { 13 | if (last_parm == '') { 14 | var url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?type_list=268435455&uid=' + userId; 15 | var result = $.getApi(url); 16 | if (result.code == 0) { 17 | var cards = result.data.cards; 18 | if (cards != null) { 19 | for (var index = 0; index < cards.length; index++) 20 | addItem(cards[index]); 21 | if (cards.length > 1) 22 | last_parm = cards[cards.length - 1].desc.dynamic_id; 23 | } 24 | } 25 | else { 26 | alert('获取动态失败!' + result.message); 27 | } 28 | } 29 | else { 30 | var url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_history?offset_dynamic_id=' + last_parm + '&type_list=268435455&uid=' + userId; 31 | var result = $.getApi(url); 32 | if (result.code == 0) { 33 | var cards = result.data.cards; 34 | if (cards != null) { 35 | for (var index = 0; index < cards.length; index++) 36 | addItem(cards[index]); 37 | if (cards.length > 1) 38 | last_parm = cards[cards.length - 1].desc.dynamic_id; 39 | } 40 | } 41 | else { 42 | alert('获取动态失败!' + result.message); 43 | } 44 | } 45 | } 46 | else { 47 | var mid = $.getData('mid'); 48 | var url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?offset_dynamic_id=' + last_parm + '&visitor_uid=' + 49 | mid + '&host_uid=' + userId + '&need_top=1'; 50 | var result = $.getApi(url); 51 | if (result.code == 0) { 52 | var cards = result.data.cards; 53 | if (cards != null) { 54 | for (var index = 0; index < cards.length; index++) 55 | addItem(cards[index]); 56 | if (cards.length > 1) 57 | last_parm = cards[cards.length - 1].desc.dynamic_id; 58 | } 59 | } 60 | else { 61 | alert('获取动态失败!' + result.message); 62 | } 63 | } 64 | } 65 | function addItem(item) { 66 | try { 67 | var dynamic_id = item.desc.dynamic_id; 68 | if ($('*[data-id="' + dynamic_id + '"]').length == 0) { 69 | var uname = ''; 70 | if (item.desc.user_profile != null) 71 | uname = item.desc.user_profile.info.uname; 72 | else if (typeof item.season == "undefined" && item.season != null) 73 | uname = item.season.title; 74 | var html = '
'; 75 | var card = JSON.parse(item.card); 76 | switch (item.desc.type) { 77 | case 1: { 78 | var content = card.item.content; 79 | html += '
' + content + '
'; 80 | 81 | html + '
'; 82 | break; 83 | } 84 | case 2: { 85 | var desc = card.item.description; 86 | var pictures = card.item.pictures; 87 | html += '
' + desc + '
'; 88 | if (pictures != null && pictures.length > 0) { 89 | var src = buildImageGrid(pictures); 90 | html += src; 91 | } 92 | html + '
'; 93 | break; 94 | } 95 | case 4: { 96 | var content = card.item.content; 97 | html += '
' + content + '
'; 98 | break; 99 | } 100 | case 8: { 101 | var aid = card.aid; 102 | var cid = card.cid; 103 | var bvid = item.desc.bvid; 104 | var view = card.stat.view; 105 | var danmaku = card.stat.danmaku; 106 | html += '
' + card.desc 107 | + '

' + 108 | card.title + '

播放:' + view + '

弹幕:' + danmaku + '

'; 109 | break; 110 | } 111 | case 64: { 112 | var id = card.id; 113 | var view = card.stats.view; 114 | var like = card.stats.like; 115 | var cover = card.image_urls[0]; 116 | html += '

' + 117 | card.title + '

浏览:' + view + '

点赞' + like + '

'; 118 | break; 119 | } 120 | case 256: { 121 | var id = card.id; 122 | var cover = card.cover; 123 | html += '

' + 124 | card.title + '

'; 125 | break; 126 | } 127 | case 512: { 128 | var play = card.stat.play; 129 | var id = card.season.season_id; 130 | var danmaku = card.stat.danmaku; 131 | var ts = parseFloat(card.player_info.expire_time + '000') 132 | var dt = new Date(ts); 133 | var time = dt.getFullYear() + '-' + (dt.getMonth() + 1) + '-' + dt.getDate() + ' ' + dt.getHours() + ':' + dt.getMinutes() + '更新'; 134 | html += '
' + time + '

' + card.card_show_title + '

播放:' + play + '

弹幕:' + danmaku + '

'; 136 | break; 137 | } 138 | case 2048: { 139 | var title = card.sketch.title; 140 | var desc = card.vest.desc_text; 141 | var cover = card.sketch.cover_url; 142 | var link = card.sketch.target_url; 143 | html += '
' + desc + '

' + title + '

' + card.sketch.desc_text + '

'; 145 | break; 146 | } 147 | default: { 148 | html += '
不支持的类型:' + item.desc.type + '
'; 149 | break; 150 | } 151 | } 152 | html + '
'; 153 | $('.items').append(html); 154 | } 155 | } 156 | catch (e) { 157 | console.log(e); 158 | console.log(card); 159 | } 160 | } 161 | function openLink() { 162 | const items = document.querySelectorAll('.item'); 163 | const targetElement = items[current]; 164 | var content = $(targetElement).find('.content'); 165 | var type = $(content).attr('data-type'); 166 | switch (parseInt(type)) { 167 | case 8: { 168 | var aid = $(content).attr('data-aid'); 169 | var cid = $(content).attr('data-cid'); 170 | var bvid = $(content).attr('data-bvid'); 171 | window.location.href = '../player/index.html?aid=' + aid + '&cid=' + cid + '&bvid=' + bvid + '&type=dynamic'; 172 | break; 173 | } 174 | case 64: { 175 | var id = $(content).attr('data-id'); 176 | window.location.href = '../web/index.html?id=' + id; 177 | break; 178 | } 179 | case 256: { 180 | var id = $(content).attr('data-id'); 181 | window.location.href = '../songinfo/index.html?id=' + id; 182 | break; 183 | } 184 | case 512: { 185 | var id = $(content).attr('data-id'); 186 | window.location.href = '../bandetail/index.html?id=' + id; 187 | break; 188 | } 189 | case 2048: { 190 | var link = $(content).attr('data-link'); 191 | sessionStorage.setItem('link', link); 192 | window.location.href = '../web/index.html'; 193 | break; 194 | } 195 | default: { 196 | var id = $(content).attr('data-id'); 197 | window.location.href = '../dydetail/index.html?id=' + id; 198 | break; 199 | } 200 | } 201 | } 202 | function buildImageGrid(pics) { 203 | var html = '
'; 204 | var len = pics.length, row2 = window.innerWidth / 2, row3 = window.innerWidth / 3; 205 | var cw = Math.floor((len == 3 || len > 4) ? row3 : row2); 206 | for (var index = 0; index < len; index++) 207 | html += ''; 208 | return html + '
'; 209 | } 210 | function handleKeydown(e) { 211 | $.clearEvent(e); 212 | switch (e.key) { 213 | case 'ArrowUp': 214 | nav(-1); 215 | break; 216 | case 'ArrowDown': 217 | nav(1); 218 | break; 219 | case 'Enter': 220 | loadData(); 221 | break; 222 | case 'Q': 223 | case 'SoftLeft': 224 | openLink(); 225 | break; 226 | case 'E': 227 | case 'Backspace': 228 | case 'SoftRight': 229 | window.location.href = '../user/index.html?mid=' + userId; 230 | break; 231 | } 232 | } 233 | var current = -1; 234 | function nav(move) { 235 | var next = current + move; 236 | const items = document.querySelectorAll('.item'); 237 | if (next >= items.length) { 238 | next = items.length - 1; 239 | } 240 | else if (next < 0) { 241 | next = 0; 242 | } 243 | const targetElement = items[next]; 244 | if (targetElement) { 245 | current = next; 246 | targetElement.focus(); 247 | $('.item').removeClass('select'); 248 | $(targetElement).addClass('select'); 249 | var h = $(targetElement).height(); 250 | if (move > 0) { 251 | scrollTo(0, scrollHeight); 252 | scrollHeight += h; 253 | } 254 | else { 255 | scrollHeight -= h; 256 | scrollTo(0, scrollHeight); 257 | } 258 | } 259 | } -------------------------------------------------------------------------------- /application/user/index.js: -------------------------------------------------------------------------------- 1 | let userId = 0; 2 | let isOpen = false, selfvalue = false; 3 | 4 | let urlQrCode = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header" 5 | //urlQrCode = "http://passport.bilibili.com/qrcode/getLoginUrl" 6 | urlQrCode = 'https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code' 7 | var intervalCheck = null; 8 | let qrcode_key = "" 9 | let qrUrl = "" 10 | function loadLoginQrCode() 11 | { 12 | if(intervalCheck) 13 | { 14 | clearInterval(intervalCheck) 15 | } 16 | var data = $.postApi(urlQrCode,'local_id=0',tv); 17 | if(data.code!=0) 18 | { 19 | alert(data.message) 20 | return; 21 | } 22 | var url = data.data.url 23 | //qrcode_key = data.data.qrcode_key 24 | qrcode_key = data.data.auth_code 25 | document.getElementById('qrcodeimg').innerHTML='' 26 | new QRCode('qrcodeimg', { 27 | text: url, 28 | width: 200, 29 | height: 200, 30 | colorDark: '#000000', 31 | colorLight: '#ffffff', 32 | correctLevel: QRCode.CorrectLevel.H //纠错等级 33 | }); 34 | $.golbalhideLoading = true; 35 | intervalCheck = setInterval(function(){ 36 | var urlPoll="https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key="+qrcode_key+"&source=main-fe-header" 37 | //var urlPoll = 'http://passport.bilibili.com/qrcode/getLoginInfo' 38 | urlPoll='https://passport.bilibili.com/x/passport-tv-login/qrcode/poll' 39 | var dataPoll = $.postApi(urlPoll,'local_id=0&auth_code='+qrcode_key,tv); 40 | 41 | //var dataPoll = $.postApi(urlPoll,"oauthKey="+qrcode_key); 42 | //console.log(dataPoll) 43 | var code = dataPoll.code 44 | if (code == 0) { 45 | clearInterval(intervalCheck) 46 | $.golbalhideLoading = false; 47 | var token = dataPoll.data.token_info; 48 | userId = token.mid; 49 | localStorage.setItem('mid', token.mid); 50 | localStorage.setItem('access_token', token.access_token); 51 | localStorage.setItem('refresh_token', token.refresh_token); 52 | localStorage.setItem('expires_in', (token.expires_in + $.getTs())); 53 | alert('登录成功!'); 54 | setUserInfo(); 55 | } 56 | else if(code==86090) 57 | { 58 | $('#logintips').text("请点击登录"); 59 | } 60 | else if(code==86101 || code==86039){ 61 | $('#logintips').text("请使用哔哩app扫码登录"); 62 | } 63 | else if(code == 86038) 64 | { 65 | clearInterval(intervalCheck) 66 | $.golbalhideLoading = false; 67 | //loadLoginQrCode() 68 | } 69 | else { 70 | alert('登录失败!' + dataPoll.message); 71 | clearInterval(intervalCheck) 72 | $.golbalhideLoading = false; 73 | } 74 | },1000) 75 | } 76 | function refresh_self() { 77 | var mid = $.getQueryVar('mid'); 78 | if (!mid) { 79 | selfvalue = true; 80 | var id = $.getData('mid'); 81 | if (typeof id != 'undefined' && id != null && id != '') { 82 | userId = parseInt(id); 83 | $('#softkey-left').text('刷新'); 84 | setUserInfo(); 85 | } 86 | else { 87 | $('#softkey-left').text('刷新'); 88 | $(".login").show(); 89 | $(".info").hide(); 90 | loadLoginQrCode(); 91 | } 92 | } 93 | else { 94 | $('#softkey-left').text('刷新'); 95 | var id = $.getData('mid'); 96 | if (id == mid) { 97 | selfvalue = true; 98 | softkey("刷新", "", "选项"); 99 | } 100 | userId = mid; 101 | setUserInfo(); 102 | } 103 | document.activeElement.addEventListener('keydown', handleKeydown); 104 | } 105 | 106 | $(refresh_self); 107 | 108 | function handleKeydown(e) { 109 | $.clearEvent(e); 110 | switch (e.key) { 111 | case 'ArrowUp': 112 | nav(-1); 113 | break; 114 | case 'ArrowDown': 115 | nav(1); 116 | break; 117 | case 'Q': 118 | case 'SoftLeft': 119 | if (!isOpen) { 120 | if (userId == 0) 121 | { 122 | loadLoginQrCode(); 123 | //login(); 124 | } 125 | else{ 126 | //logout(); 127 | selfvalue=false; 128 | setUserInfo(); 129 | refresh_self(); 130 | } 131 | } 132 | else { 133 | navigate(); 134 | } 135 | break; 136 | case 'Enter': 137 | if (!isOpen) 138 | window.location.href = '../index.html'; 139 | break; 140 | case 'Backspace': 141 | window.location.href = '../index.html'; 142 | break; 143 | case 'E': 144 | case 'SoftRight': 145 | showhideMenu(); 146 | break; 147 | } 148 | } 149 | function navigate() { 150 | var item = $($('.menuitem')[menuIndex]).attr('data-tag'); 151 | switch (item) { 152 | case 'cb': 153 | window.location.href = '../contribution/index.html?mid=' + userId; 154 | break; 155 | case 'dy': 156 | window.location.href = '../dynamic/index.html?mid=' + userId; 157 | break; 158 | case 'ct': 159 | window.location.href = '../collection/index.html'; 160 | break; 161 | case 'at': 162 | window.location.href = '../attention/index.html'; 163 | break; 164 | case 'logout': 165 | logout(); 166 | showhideMenu(); 167 | break; 168 | 169 | } 170 | } 171 | 172 | function showhideMenu() { 173 | if (isOpen) { 174 | $("#menu").hide(); 175 | softkey("刷新", "主页", "选项"); 176 | isOpen = false; 177 | } 178 | else { 179 | if (!selfvalue) { 180 | $('*[data-tag="at"]').hide(); 181 | $('*[data-tag="ct"]').hide(); 182 | } 183 | menuIndex=0; 184 | $("#menu").show(); 185 | var items = document.querySelectorAll('.menuitem'); 186 | items.forEach(function (item, index) { 187 | $(item).removeClass('select'); 188 | }); 189 | var items = document.querySelectorAll('.menuitem:not([style*="display:none"]):not([style*="display: none"]'); 190 | items[0].focus(); 191 | $(items[0]).addClass('select'); 192 | softkey("选择", "主页", "返回"); 193 | isOpen = true; 194 | } 195 | } 196 | 197 | function softkey(left, center, right) { 198 | $('#softkey-left').text(left); 199 | $('#softkey-center').text(center); 200 | $('#softkey-right').text(right); 201 | } 202 | 203 | function logout() { 204 | userId = 0; 205 | $(".info").hide(); 206 | $(".login").show(); 207 | $('#softkey-left').text('登录'); 208 | localStorage.removeItem('mid'); 209 | localStorage.removeItem('access_token'); 210 | localStorage.removeItem('refresh_token'); 211 | localStorage.removeItem('expires_in'); 212 | localStorage.removeItem('userInfo'); 213 | } 214 | 215 | var current = -1, menuIndex = 0; 216 | function nav(move) { 217 | if (!isOpen) { 218 | var next = current + move; 219 | const items = document.querySelectorAll('.item'); 220 | if (next >= items.length) { 221 | next = items.length - 1; 222 | } 223 | else if (next < 0) { 224 | next = 0; 225 | } 226 | const targetElement = items[next]; 227 | if (targetElement) { 228 | current = next; 229 | targetElement.focus(); 230 | $('.item').removeClass('select'); 231 | $(targetElement).addClass('select'); 232 | } 233 | } 234 | else { 235 | var next = menuIndex + move; 236 | var items = document.querySelectorAll('.menuitem:not([style*="display:none"]):not([style*="display: none"]'); 237 | //console.log(items) 238 | if (next >= items.length) { 239 | next = items.length - 1; 240 | } 241 | else if (next < 0) { 242 | next = 0; 243 | } 244 | const targetElement = items[next]; 245 | if (targetElement) { 246 | menuIndex = next; 247 | targetElement.focus(); 248 | $('.menuitem').removeClass('select'); 249 | $(targetElement).addClass('select'); 250 | } 251 | } 252 | } 253 | 254 | function login() { 255 | //var username = $('#name').val(); 256 | //var pwd = $('#pwd').val(); 257 | var username = document.getElementById('name').value; 258 | var pwd = document.getElementById('pwd').value; 259 | if (username == '' || pwd == '') { 260 | alert('账号或者密码不能为空!'); 261 | } 262 | else { 263 | var passwd = encryptedPwd(pwd); 264 | var content = 'username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(passwd) + '&gee_type=10'; 265 | var data = $.postApi('https://passport.bilibili.com/api/v3/oauth2/login', content, tv); 266 | if (data.code == 0) { 267 | var token = data.data.token_info; 268 | userId = token.mid; 269 | localStorage.setItem('mid', token.mid); 270 | localStorage.setItem('access_token', token.access_token); 271 | localStorage.setItem('refresh_token', token.refresh_token); 272 | localStorage.setItem('expires_in', (token.expires_in + $.getTs())); 273 | alert('登录成功!'); 274 | setUserInfo(); 275 | } 276 | else { 277 | alert('登录失败!' + data.message); 278 | } 279 | } 280 | } 281 | 282 | function setUserInfo() { 283 | var userInfo = null; 284 | if (selfvalue) 285 | userInfo = $.getData('userInfo'); 286 | if (typeof userInfo == 'undefined' || userInfo == null || userInfo == '') { 287 | var url = 'https://app.bilibili.com/x/v2/space?ps=10&vmid=' + userId; 288 | var result = $.getApi(url); 289 | userInfo = JSON.stringify(result); 290 | } 291 | var info = JSON.parse(userInfo); 292 | if (info != null) { 293 | $('#face').attr('src', info.data.card.face); 294 | $('#uid').text('UID ' + info.data.card.mid); 295 | $('#uname').text(info.data.card.name); 296 | $('#exp').text('经验 ' + info.data.card.level_info.current_exp + ' / ' + info.data.card.level_info.next_exp); 297 | $('#lv').text('LV ' + info.data.card.level_info.current_level); 298 | $('#focus').text(' 关注 ' + info.data.card.attention); 299 | $('#fans').text(' 粉丝 ' + info.data.card.fans); 300 | $('#sign').text(info.data.card.sign); 301 | } 302 | if (selfvalue) { 303 | localStorage.setItem('userInfo', userInfo); 304 | //$('#softkey-left').text('注销'); 305 | } 306 | $(".login").hide(); 307 | $(".info").show(); 308 | } 309 | 310 | function encryptedPwd(pwd) { 311 | var encrypted = pwd; 312 | var data = $.postApi("https://passport.bilibili.com/api/oauth2/getKey", '', android); 313 | if (data != null && data.code == 0) { 314 | var key = data.data.key; 315 | var hash = data.data.hash; 316 | key = key.replace(/\n/g, '').replace('-----BEGIN PUBLIC KEY-----', '').replace('-----END PUBLIC KEY-----', ''); 317 | var decrypt = new JSEncrypt(); 318 | decrypt.setPublicKey(key); 319 | var hashPass = hash.concat(pwd); 320 | encrypted = decrypt.encrypt(hashPass); 321 | if (typeof encrypted == 'boolean' && encrypted == false) { 322 | //加密失败,放弃挣扎吧 323 | encrypted = pwd; 324 | } 325 | } 326 | return encrypted; 327 | } 328 | -------------------------------------------------------------------------------- /application/player/index.js: -------------------------------------------------------------------------------- 1 | var commentpage = 1, islike = 0, qn = 16, danmaku = 0; 2 | let player = null; 3 | let aid = 0, bvid = 0, cid = 0, mid = 0, season_type = 0; 4 | $(function () { 5 | mid = $.getData('mid'); 6 | qn = $.getData('video_qn'); 7 | if (qn == '') qn = 16; 8 | danmaku = $.getData('danmaku'); 9 | if (danmaku == '') danmaku = 0; 10 | aid = $.getQueryVar('aid'); 11 | cid = $.getQueryVar('cid'); 12 | bvid = $.getQueryVar('bvid'); 13 | season_type = $.getQueryVar('season_type'); 14 | document.activeElement.addEventListener('keydown', handleKeydown); 15 | if (season_type === false) 16 | getParts(); 17 | else { 18 | $('#pages').hide(); 19 | getBangmiPlayUrl(); 20 | } 21 | getInfo(); 22 | getIsLike(); 23 | window.addEventListener('error', function (error) { 24 | console.log(error); 25 | }); 26 | }); 27 | function playVideo(url, type, position) { 28 | if (typeof player !== "undefined") { 29 | if (player != null) { 30 | player.unload(); 31 | player.detachMediaElement(); 32 | player.destroy(); 33 | player = null; 34 | } 35 | } 36 | player = flvjs.createPlayer({ 37 | type: type, 38 | isLive: false, 39 | url: url 40 | }); 41 | player.on(flvjs.Events.ERROR, function () { 42 | var t = this.currentTime; 43 | playVideo(url, type, t); 44 | }); 45 | player.attachMediaElement(document.getElementById('player')); 46 | player.load(); 47 | if (typeof position !== 'undefined') 48 | player.currentTime = position; 49 | player.play(); 50 | } 51 | function openV() { 52 | const currentIndex = document.activeElement.tabIndex; 53 | window.location.href = './player/index.html?aid=' + aid[currentIndex] + '&bvid=' + bvid[currentIndex] 54 | } 55 | function playV(part) { 56 | if (season_type === false) { 57 | if (qn == '16' || qn == 16) { 58 | var url = 'https://www.bilibili.com/video/'; 59 | if (bvid === false) 60 | url += 'av' + aid; 61 | else 62 | url += bvid; 63 | url += '?p=' + part; 64 | var result = $.getWeb(url); 65 | try { 66 | var playurl = result.match(/readyVideoUrl: \'(.*?)\',/g).toString(); 67 | playurl = playurl.replace("readyVideoUrl: '", ""); 68 | playurl = playurl.replace("',", ""); 69 | if (playurl) { 70 | var player = document.getElementById("player"); 71 | player.src = playurl; 72 | player.width = 240; 73 | player.height = 150; 74 | player.play(); 75 | $.Async().then(function () { 76 | if (danmaku == 1) 77 | $.getDanmaku('palyercontainter', 'player', cid); 78 | }); 79 | } 80 | } 81 | catch (err) { 82 | console.log(err); 83 | getPlayUrl(part); 84 | } 85 | } 86 | else { 87 | getPlayUrl(part); 88 | } 89 | } 90 | else { 91 | getBangmiPlayUrl(); 92 | } 93 | } 94 | function getPlayUrl(part) { 95 | cid = playInfos[part - 1].cid; 96 | var link = 'https://api.bilibili.com/x/player/playurl?avid=' + aid + '&cid=' + cid + '&qn=' + qn + '&type=&otype=json'; 97 | if (qn == '16' || qn == 16) 98 | link += '&platform=html5'; 99 | var result = $.getApi(link, web); 100 | if (result.code == 0) { 101 | var url = result.data.durl[0].url; 102 | if (url) { 103 | var type = 'flv'; 104 | if (url.indexOf('flv') == -1) 105 | type = 'mp4'; 106 | playVideo(url, type); 107 | } 108 | } 109 | } 110 | //just for bangmi 111 | function getBangmiPlayUrl() { 112 | var result = false; 113 | try { 114 | var url = 'https://api.bilibili.com/pgc/player/web/playurl?cid=' + cid + '&otype=json&type=&quality=' + qn + '&module=bangumi&season_type=' 115 | + season_type + '&qn=' + qn; 116 | var result = $.getApi(url, web); 117 | if (result.code == 0) { 118 | if (result.result.durl != null && result.result.durl.length > 0) { 119 | var url = result.result.durl[0].url; 120 | console.log(url) 121 | var type = 'flv'; 122 | if (url.indexOf('flv') == -1) 123 | type = 'mp4'; 124 | playVideo(url, type); 125 | result = true; 126 | } 127 | } 128 | else { 129 | console.log(result); 130 | alert("视频直链解析失败!"); 131 | } 132 | } 133 | catch (e) { 134 | console.log(e); 135 | alert("视频直链解析失败!"); 136 | } 137 | return result; 138 | } 139 | function add0(m) { 140 | return m < 10 ? '0' + m : m; 141 | } 142 | function formattime(ts) { 143 | var time = new Date(ts * 1000); 144 | var y = time.getFullYear(); 145 | var m = time.getMonth() + 1; 146 | var d = time.getDate(); 147 | var h = time.getHours(); 148 | var mm = time.getMinutes(); 149 | var s = time.getSeconds(); 150 | return y + '-' + add0(m) + '-' + add0(d) + ' ' + add0(h) + ':' + add0(mm) + ':' + add0(s); 151 | } 152 | var username = "UP主"; 153 | var uid = 0; 154 | function appendComments(item, tabIndex) { 155 | var content = item.content.message; 156 | var uname = item.member.uname; 157 | var avatar = item.member.avatar + '@40w_40h.jpg'; 158 | var ctime = formattime(item.ctime); 159 | $('.items').append('

' + content + '

'); 161 | } 162 | function getComments(page) { 163 | if (page) { } 164 | else { 165 | $('.items').empty(); 166 | $('.items').append('正在加载…'); 167 | commentpage = 1; 168 | page = 1; 169 | } 170 | url = 'https://api.bilibili.com/x/v2/reply?jsonp=jsonp&pn=' + page + '&type=1&sort=2&oid=' + aid; 171 | $.getJSON(url, function (result) { 172 | if (result.data.replies) { 173 | $('.items').empty(); 174 | $.each(result.data.replies, function (r, item) { 175 | appendComments(item, r + ''); 176 | }) 177 | } 178 | else { 179 | alert("没有更多评论了!"); 180 | return; 181 | } 182 | if (document.querySelectorAll('.itemcomment')[0]) { 183 | document.querySelectorAll('.itemcomment')[0].focus(); 184 | } 185 | }).fail(function (jqXHR, status, error) { 186 | alert(error + ",请求可能被拦截"); 187 | }); 188 | }; 189 | function getInfo() { 190 | $.getJSON('https://api.bilibili.com/x/web-interface/view?aid=' + aid, function (result) { 191 | var title = result.data.title; 192 | var view = result.data.stat.view; 193 | var danmaku = result.data.stat.danmaku; 194 | var like = result.data.stat.like; 195 | var coin = result.data.stat.coin; 196 | var favorite = result.data.stat.favorite; 197 | $('.items').empty(); 198 | $('.items').append("") 199 | $('.items').append("") 200 | $('.items').append("

" + result.data.desc + "

"); 201 | uid = result.data.owner.mid; 202 | username = result.data.owner.name; 203 | getIsLike(uid); 204 | document.querySelectorAll('.item')[0].focus(); 205 | }); 206 | } 207 | function toggleFullScreen() { 208 | if (!document.fullscreenElement) { 209 | document.documentElement.requestFullscreen(); 210 | } 211 | else { 212 | if (document.exitFullscreen) 213 | document.exitFullscreen(); 214 | } 215 | } 216 | function handleKeydown(e) { 217 | $.clearEvent(e); 218 | switch (e.key) { 219 | case 'ArrowUp': 220 | nav(-1); 221 | break; 222 | case 'ArrowDown': 223 | nav(1); 224 | break; 225 | case 'ArrowRight': 226 | tab(1); 227 | break; 228 | case 'ArrowLeft': 229 | tab(-1); 230 | break; 231 | case 'Enter': 232 | enter(); 233 | break; 234 | case 'Backspace': 235 | if ($('#player').attr('class') == 'video_fullscreen') { 236 | document.exitFullscreen(); 237 | $('#player').attr('class', 'video_normal'); 238 | } 239 | else { 240 | var type = $.getQueryVar('type'); 241 | if (type === false) 242 | window.location.href = '../index.html?ref=' + $.getQueryVar('ref'); 243 | else { 244 | var id = $.getQueryVar('id'); 245 | var mid = $.getQueryVar('mid'); 246 | if (id === false && mid === false) 247 | window.location.href = '../' + type + '/index.html'; 248 | else if (mid === false) 249 | window.location.href = '../' + type + '/index.html?id=' + id; 250 | else 251 | window.location.href = '../' + type + '/index.html?mid=' + mid; 252 | } 253 | } 254 | break; 255 | case 'Q': 256 | case 'SoftLeft': 257 | if ($('#softkey-left').text() === "全屏") { 258 | if ($('#player').attr('class') == 'video_normal') { 259 | document.documentElement.requestFullscreen(); 260 | $('#player').attr('class', 'video_fullscreen'); 261 | $('#palyercontainter>canvas').addClass('fullscreen'); 262 | } 263 | else { 264 | document.exitFullscreen(); 265 | $('#player').attr('class', 'video_normal'); 266 | $('#palyercontainter>canvas').removeClass('fullscreen'); 267 | } 268 | } 269 | else if ($('#softkey-left').text() === "下一页") { 270 | commentpage += 1; 271 | getComments(commentpage); 272 | } 273 | else if ($('#softkey-left').text() === "播放") { 274 | var index = $('.pages').attr('data-index'); 275 | if (typeof index != 'undefined') { 276 | index = parseInt(index) + 1; 277 | playV(index); 278 | } 279 | } 280 | break; 281 | case 'E': 282 | case 'SoftRight': 283 | SoftRight(); 284 | break; 285 | case '2': 286 | navigator.volumeManager.requestUp(); 287 | break; 288 | case '8': 289 | navigator.volumeManager.requestDown(); 290 | break; 291 | case '4': 292 | seekTo(-1); 293 | break; 294 | case '6': 295 | seekTo(1); 296 | break; 297 | } 298 | } 299 | function seekTo(type) { 300 | try { 301 | var player = document.getElementById('player'); 302 | if (!isNaN(player.duration)) { 303 | var next = player.currentTime + (type * 10); 304 | if (next < 0) 305 | next = 0; 306 | else if (next > player.duration) 307 | next = player.duration; 308 | player.currentTime = next; 309 | player.play(); 310 | } 311 | } 312 | catch (e) { 313 | console.log(e); 314 | } 315 | } 316 | function refreshLike() { 317 | $.ajaxSettings.async = false; 318 | var data = localStorage.getItem('like'); 319 | data = JSON.parse(data); 320 | $.each(data, function (r, item) { 321 | ajax = $.getJSON('https://api.bilibili.com/x/space/acc/info?mid=' + item.uid, function (result) { 322 | data[r].pic = result.data.face 323 | data[r].nick = result.data.name 324 | }) 325 | ajax = $.getJSON('https://api.bilibili.com/x/relation/stat?vmid=' + item.uid, function (result) { 326 | data[r].sub = result.data.follower 327 | }) 328 | }) 329 | localStorage.setItem('like', JSON.stringify(data)) 330 | $.ajaxSettings.async = true; 331 | } 332 | function LikeUser(uid) { 333 | var result = localStorage.getItem('like') 334 | try { 335 | result = JSON.parse(result) 336 | } 337 | catch (e) { 338 | result = []; 339 | } 340 | result.push({ uid: uid }); 341 | localStorage.setItem('like', JSON.stringify(result)) 342 | refreshLike(); 343 | } 344 | function UnLikeUser(uid) { 345 | var result = localStorage.getItem('like') 346 | try { 347 | result = JSON.parse(result) 348 | } 349 | catch (e) { 350 | result = []; 351 | } 352 | for (var i = 0; i < result.length; i++) { 353 | if (result[i].uid === uid) { 354 | result.splice(i, 1); 355 | i--; 356 | } 357 | } 358 | localStorage.setItem('like', JSON.stringify(result)) 359 | refreshLike(); 360 | } 361 | function SoftRight() { 362 | if (tab_location == 0 || tab_location == 1) { 363 | if ($('#softkey-right').text() === '加载中' || $('#player').attr('class') == 'video_fullscreen') { 364 | return; 365 | } 366 | var islike = $('#softkey-right').text() === '取消关注'; 367 | if (islike) { 368 | if (confirm('确定取消关注"' + username + '"吗?')) { 369 | UnLikeUser(uid); 370 | $('#softkey-right').text('关注'); 371 | } 372 | } 373 | else { 374 | if (confirm('确定关注"' + username + '"吗?')) { 375 | LikeUser(uid); 376 | $('#softkey-right').text('取消关注'); 377 | } 378 | } 379 | } 380 | else if (tab_location == 2) { 381 | var text = prompt("请输入您的评论", ""); 382 | if (text != '') { 383 | var result = $.sendComment(aid, text); 384 | try { 385 | if (result.success_action == 0) 386 | alert(result.success_toast); 387 | } 388 | catch (e) { 389 | alert('发送失败!'); 390 | } 391 | } 392 | } 393 | } 394 | var tab_location = 0; 395 | function nav(move) { 396 | if (tab_location === 0) { 397 | const currentIndex = document.activeElement.tabIndex; 398 | var next = currentIndex + move; 399 | const items = document.querySelectorAll('.item'); 400 | if (next >= items.length) { 401 | next = items.length - 1; 402 | } 403 | else if (next < 0) { 404 | next = 0; 405 | } 406 | const targetElement = items[next]; 407 | if (targetElement) { 408 | targetElement.focus(); 409 | } 410 | if (next == 0) { 411 | $('.items').scrollTop(0); 412 | } 413 | if (next == 2) { 414 | $('#softkey-center').text('查看'); 415 | } else { 416 | var video = document.getElementById("player"); 417 | if (video.paused == true) { 418 | $('#softkey-center').text('播放'); 419 | } else { 420 | $('#softkey-center').text('暂停'); 421 | } 422 | } 423 | } 424 | else if (tab_location === 1) { 425 | var items = $('.pages').children(); 426 | var index = $('.pages').attr('data-index'); 427 | if (index == undefined) 428 | index = 0; 429 | else if (index < items.length) { 430 | index = parseInt(index); 431 | index += move; 432 | } 433 | if (typeof index == 'number') { 434 | $(items).removeClass('select'); 435 | const targetElement = items[index]; 436 | if (targetElement) { 437 | targetElement.focus(); 438 | $(targetElement).addClass('select'); 439 | } 440 | $('.pages').attr('data-index', index); 441 | } 442 | } 443 | else if (tab_location === 2) { 444 | const currentIndex = document.activeElement.tabIndex; 445 | var next = currentIndex + move; 446 | const items = document.querySelectorAll('.itemcomment'); 447 | if (next >= items.length) { 448 | next = items.length - 1; 449 | } 450 | else if (next < 0) { 451 | next = 0; 452 | } 453 | const targetElement = items[next]; 454 | if (targetElement) { 455 | targetElement.focus(); 456 | } 457 | if (next == 0) { 458 | $('.items').scrollTop(0); 459 | } 460 | } 461 | } 462 | function tab(move) { 463 | const currentIndex = parseInt($('.focus').attr('tabIndex')); 464 | var next = currentIndex + move; 465 | if (season_type === false) { 466 | if (next > 2) { 467 | next = 0; 468 | } 469 | else if (next < 0) { 470 | next = 2; 471 | } 472 | } 473 | else { 474 | if (next == 1) 475 | next = 2; 476 | else if (next > 2) 477 | next = 0; 478 | } 479 | const items = document.querySelectorAll('li'); 480 | const targetElement = items[next]; 481 | if (targetElement) { 482 | $('.focus').attr("class", ""); 483 | targetElement.className = "focus"; 484 | tab_location = next; 485 | if (tab_location == 0) { 486 | $('#softkey-left').text('全屏'); 487 | if (islike) { 488 | $('#softkey-right').text("取消关注"); 489 | } else { 490 | $('#softkey-right').text("关注"); 491 | } 492 | } 493 | else if (tab_location == 1) { 494 | $('#softkey-left').text('播放'); 495 | $('#softkey-center').text(''); 496 | } 497 | else if (tab_location == 2) { 498 | $('#softkey-left').text('下一页'); 499 | $('#softkey-right').text('发表评论'); 500 | } 501 | load() 502 | } 503 | } 504 | function load() { 505 | switch (tab_location) { 506 | case 0: 507 | $('.items').show(); 508 | $('.pages').hide(); 509 | getInfo(); 510 | $('#softkey-center').text("") 511 | break; 512 | case 1: 513 | $('.items').hide(); 514 | $('.pages').show(); 515 | break; 516 | case 2: 517 | $('.items').show(); 518 | $('.pages').hide(); 519 | getComments(); 520 | $('#softkey-center').text("查看") 521 | break; 522 | } 523 | } 524 | function enter() { 525 | switch (tab_location) { 526 | case 0: 527 | var currentIndex = document.activeElement.tabIndex; 528 | if (currentIndex == 2 && $('#player').attr('class') != 'video_fullscreen') { 529 | var items = document.querySelectorAll('.item'); 530 | alert($(items[currentIndex]).text()); 531 | } 532 | else { 533 | try { 534 | var video = document.getElementById("player"); 535 | if (video.paused == true) { 536 | video.play(); 537 | $('#softkey-center').text('暂停'); 538 | } else { 539 | video.pause(); 540 | $('#softkey-center').text('播放'); 541 | } 542 | } 543 | catch (err) { 544 | alert(err); 545 | } 546 | } 547 | break; 548 | case 2: 549 | var currentIndex = document.activeElement.tabIndex; 550 | var items = document.querySelectorAll('.comment'); 551 | alert($(items[currentIndex]).text()); 552 | break; 553 | } 554 | } 555 | function getIsLike(uid) { 556 | var result = localStorage.getItem('like') 557 | if(!result) 558 | { 559 | result=[] 560 | localStorage.setItem('like', "[]") 561 | } 562 | try { 563 | result = JSON.parse(result) 564 | } catch (e) { 565 | localStorage.setItem('like', "[]") 566 | $('#softkey-right').text("关注"); 567 | return; 568 | } 569 | islike = 0; 570 | for (var i = 0; i < result.length; i++) { 571 | if (result[i].uid === uid) { 572 | islike = 1; 573 | break; 574 | } 575 | } 576 | if (islike) { 577 | $('#softkey-right').text("取消关注"); 578 | } else { 579 | $('#softkey-right').text("关注"); 580 | } 581 | } 582 | function getParts() { 583 | var url = 'https://app.bilibili.com/x/v2/view?plat=0'; 584 | if (aid === false) 585 | url += '&bvid=' + bvid; 586 | else 587 | url += '&aid=' + aid; 588 | var result = $.getApi(url); 589 | if (result.code == 0) { 590 | var pages = result.data.pages; 591 | if (pages != null && pages.length > 0) { 592 | for (var index = 0; index < pages.length; index++) { 593 | playInfos.push(new playinfo(aid, pages[index], 0)); 594 | var html = '
 P' + pages[index].page + '  ' + pages[index].part + '
'; 595 | $('.pages').append(html); 596 | } 597 | playV(1); 598 | } 599 | } 600 | else { 601 | alert('获取视频地址失败!' + result.message); 602 | } 603 | } 604 | let playInfos = []; 605 | window.unload = function () { 606 | if (window.danmaku != null && typeof window.danmaku != 'undefined') 607 | window.danmaku.destroy(); 608 | } --------------------------------------------------------------------------------