给哔哩哔哩bilibili电脑版做个手机遥控器

devtools/2024/10/24 4:23:23/

前言

bilibili电脑版可以在电脑屏幕上观看bilibili视频。然而,电脑版的bilibili不能通过手机控制视频翻页和调节音量,这意味着观看视频时需要一直坐在电脑旁边。那么,有没有办法制作一个手机遥控器来控制bilibili电脑版呢?

首先,bilibili电脑版支持快捷键,可以通过一些快捷键来控制视频播放。例如,按下空格键可以控制视频的播放和暂停。

既然快捷键可以控制视频,那么我们的思路就很清晰了。可以在电脑上搭建一个HTTP服务器,部署一个遥控器样式的网页,上面放置一些简单的按钮。用户打开网页后,点击这些按钮,服务器端就会模拟用户点击键盘来实现相应的操作。

前后台代码实现

说干就干, 开始动手实现这个手机版bilibili遥控器, 语言方面我们选择使用NodeJS来搭建我们的服务器, 先写前端UI:

整体的网页框架

<html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<body>...
</body>
<script>...
</script>
</html>
  • <meta charset="utf-8">: 指定文档的字符编码为UTF-8。
  • <meta name="viewport" content="width=device-width, initial-scale=1" />: 使页面在移动设备上适应屏幕宽度,并初始缩放比例为1。

遥控器的按钮:

<button data-action="up" style="margin-bottom: 30px;width: 100%;height: 110px;">音量+</button>
<button data-action="down" style="margin-bottom: 30px;width: 100%;height: 110px;">音量-</button>
<button data-action="previous" style="margin-bottom: 30px;width: 100%;height: 110px;">上一个</button>
<button data-action="next" style="margin-bottom: 30px;width: 100%;height: 110px;">下一个</button>
<button data-action="pauseOrPlay" style="margin-bottom: 30px;width: 100%;height: 110px;">暂停/播放</button>

每个按钮都有一个 data-action 属性,用于定义按钮的动作。

按钮的样式通过 style 属性设置,按钮高度110px,宽度100%,且每个按钮的底部都有30px的间距。

Javascript代码

document.querySelectorAll('button[data-action]').forEach(button => {button.addEventListener('click', () => {const action = button.getAttribute('data-action');fetch(`${window.location.origin}/${action}`).then(response => response.json()).then(data => {console.log(data);}).catch(error => {alert('Error fetching data:', error);});});
});

首先代码中会选择所有带有 data-action 属性的按钮。

为每个按钮添加点击事件监听器。

点击按钮后,会获取按钮的 data-action 属性值,并发起一个fetch请求

整体的网页代码

整体的网页代码如下:

<html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" /><body><button data-action="up" style="margin-bottom: 30px;width: 100%;height: 110px;">音量+</button><br><button data-action="down" style="margin-bottom: 30px;width: 100%;height: 110px;">音量-</button><br><button data-action="previous" style="margin-bottom: 30px;width: 100%;height: 110px;">上一个</button><br><button data-action="next" style="margin-bottom: 30px;width: 100%;height: 110px;">下一个</button><br><button data-action="pauseOrPlay" style="margin-bottom: 30px;width: 100%;height: 110px;">暂停/播放</button><br>
</body><script>document.querySelectorAll('button[data-action]').forEach(button => {button.addEventListener('click', () => {const action = button.getAttribute('data-action');fetch(`${window.location.origin}/${action}`).then(response => response.json()).then(data => {console.log(data);}).catch(error => {alert('Error fetching data:', error);});});});
</script></html>

预览效果

网页在手机浏览器里打开的效果如下图所示:

后端HTTP服务器实现

剩下的就是服务端了, 主要用来接受http请求, 触发不同的键盘事件即可.

整体代码

const path = require("path");
const ks = require('node-key-sender');
const express = require('express');
const app = express();
const port = 3000;const actions = {next: () => ks.sendKey('down'),previous: () => ks.sendKey('up'),up: () => ks.sendCombination(['shift', 'up']),down: () => ks.sendCombination(['shift', 'down']),pauseOrPlay: () => ks.sendKey('space')
};Object.keys(actions).forEach(action => {app.get(`/${action}`, async (req, res) => {try {await actions[action]();res.json({ success: true, message: `${action} action completed` });} catch (error) {res.status(500).json({ success: false, message: `Error performing ${action} action`, error });}});
});app.get('/', (req, res) => {res.sendFile(path.join(__dirname, 'index.html'));
});app.listen(port, () => {console.log(`Example app listening on port ${port}`);
});

代码解释

引入模块

const path = require("path");
const ks = require('node-key-sender');
const express = require('express');

node-key-sender: 这个模块用于发送模拟键盘按键事件。

express: 用于创建Web服务器的Node.js框架。

创建Express应用和设置端口

const app = express();
const port = 3000;


定义动作(Actions)对象

const actions = {next: () => ks.sendKey('down'),previous: () => ks.sendKey('up'),up: () => ks.sendCombination(['shift', 'up']),down: () => ks.sendCombination(['shift', 'down']),pauseOrPlay: () => ks.sendKey('space')
};

这里定义了五个动作,每个动作对应一个键盘事件。

创建路由

Object.keys(actions).forEach(action => {app.get(`/${action}`, async (req, res) => {try {await actions[action]();res.json({ success: true, message: `${action} action completed` });} catch (error) {res.status(500).json({ success: false, message: `Error performing ${action} action`, error });}});
});


使用 Object.keys(actions) 获取所有动作的名称,并为每个动作创建一个对应的路由。

处理请求时,调用相应的动作,并返回JSON格式的响应。

返回静态网页

app.get('/', (req, res) => {res.sendFile(path.join(__dirname, 'index.html'));
});

这个路由将根路径 (/) 的请求返回 index.html 文件。

启动服务器

app.listen(port, () => {console.log(`Example app listening on port ${port}`);
});

服务器监听指定端口(这里是3000),并在启动时输出提示信息。

添加上package.json文件

package.json文件用来描述dependencies信息

{"name": "bilibili-remote-control","version": "1.0.0","description": "Bilibili遥控器","main": "index.js","scripts": {"start": "node index.js"},"author": "","license": "MIT","dependencies": {"express": "^4.17.1","node-key-sender": "^1.0.11"}
}

运行手机遥控器

整个代码就完成了, 现在可以启动遥控器了:

装上dependencies

npm install

运行遥控器

npm run start

可以看到服务器已经启动起来了

手机浏览器里打开192.168.x.x开头的网页, 然后运行bilibili桌面版, 即可在手机里面控制bilibili的播放了, 再也不用坐在电脑屏幕跟前了.

总结

以上便是给整个bilibili手机版遥控器介绍, 相关代码已经发布到CSDN, 可以直接访问: bilibili-remote-controller:Bilibili电脑版手机遥控器 - GitCode


http://www.ppmy.cn/devtools/128355.html

相关文章

pdf文件怎样一张纸打印四页

在日常工作和学习中&#xff0c;我们经常会遇到需要将PDF文件中的多页内容合并打印到一张纸上的情况&#xff0c;比如将四页内容打印到一张A4纸上&#xff0c;以节省纸张和成本。同时&#xff0c;在打开pdf文件的方式&#xff0c;一般都是通过电脑浏览器打印&#xff0c;因此对…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

中小型医院网站:Spring Boot开发策略

2 相关技术简介 2.1 Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;…

Linux_进程终止_进程等待_进程替换

进程终止 不知道大家想过没有&#xff0c;我们写的main()函数的返回值是返回给谁的呢&#xff1f;其实是返回给父进程或者系统的。 int main() {std::cout << "hello" << std::endl;return 10; }运行该代码&#xff0c;输入hello&#xff0c;没问题&am…

Jetpack架构组件_LiveData组件

1.LiveData初识 LiveData:ViewModel管理要展示的数据&#xff08;VM层类似于原MVP中的P层&#xff09;&#xff0c;处理业务逻辑&#xff0c;比如调用服务器的登陆接口业务。通过LiveData观察者模式&#xff0c;只要数据的值发生了改变&#xff0c;就会自动通知VIEW层&#xf…

Spring Boot + Vue 前后端分离项目总结:解决 CORS 和 404 问题

Spring Boot Vue 前后端分离项目总结&#xff1a;解决 CORS 和 404 问题 在进行前后端分离的项目开发中&#xff0c;我们遇到了几个关键问题&#xff1a;跨域问题 (CORS) 和 404 路由匹配错误。以下是这些问题的详细分析和最终的解决方案。 问题描述 跨域请求被阻止 (CORS) 当…

11.学生成绩管理系统(Java项目基于SpringBoot + Vue)

目录 1.系统的受众说明 2 总体设计 2.1 需求概述 2.2 软件结构 3 模块设计 3.1 模块基本信息 3.2 功能概述 3.3 算法 3.4 模块处理逻辑 4 数据库设计 4.1 E-R图 4.2 表设计 4.2.1 管理员信息表 4.2.2 课程基本信息表 4.2.3 课程扩展信息表 4.2.4 专业信…

【华为HCIP实战课程十三】OSPF网络中3类LSA及区域间负载均衡,网络工程师

一、ABR SW1查看OSPF ABR为R4而非R3,因为R4连接骨干区域0,R3没有连接到区域0 R6查看OSPF路由: 二、查看3类LSA,由于R6不是ABR因此自身不会产生3类LSA 但是有区域间路由就可以看到3类LSA