parent
99c196afad
commit
8cdf2a6655
|
|
@ -0,0 +1,121 @@
|
||||||
|
/* 哔哩小窗样式 */
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
img{
|
||||||
|
max-width: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: inherit;
|
||||||
|
transition: color .3s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-box{
|
||||||
|
color: #555;
|
||||||
|
height: 10em;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-box.white{ background: #fff }
|
||||||
|
.bili-box.gray{ background: #f9f9f9 }
|
||||||
|
.bili-box.black{
|
||||||
|
color: #eee;
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
.bili-box h1{
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 1.05em;
|
||||||
|
font-weight: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-bottom: .5em;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.bili-box h1 a:hover{
|
||||||
|
color: #4cb1f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-box .bili-img{
|
||||||
|
flex: 0 0 30%;
|
||||||
|
max-width: 30%;
|
||||||
|
}
|
||||||
|
.bili-box .bili-img img{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-box .bili-info{
|
||||||
|
padding: 1em;
|
||||||
|
max-width: 70%;
|
||||||
|
}
|
||||||
|
.bili-info p{
|
||||||
|
opacity: .75;
|
||||||
|
font-size: .85em;
|
||||||
|
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: clip;
|
||||||
|
}
|
||||||
|
.bili-powered{
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
color: #fff;
|
||||||
|
opacity: .8;
|
||||||
|
padding: .5em;
|
||||||
|
line-height: 1;
|
||||||
|
font-size: .5em;
|
||||||
|
position: absolute;
|
||||||
|
background: #4cb1f3;
|
||||||
|
transition: opacity .3s;
|
||||||
|
border-radius: 1em 0 0 0;
|
||||||
|
}
|
||||||
|
.bili-powered:hover{ opacity: 1 }
|
||||||
|
.black .bili-powered{ background: #0d5e92 }
|
||||||
|
|
||||||
|
.bili-hidden{ display: none }
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px){
|
||||||
|
.bili-box .bili-info{
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
max-width: none;
|
||||||
|
font-size: .875em;
|
||||||
|
padding: 1em .75em;
|
||||||
|
background: rgba(0, 0, 0, .5);
|
||||||
|
-webkit-backdrop-filter: blur(3px);
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-info p{
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-box .bili-img{
|
||||||
|
flex: 1;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bili-powered{
|
||||||
|
top: 0;
|
||||||
|
bottom: inherit;
|
||||||
|
border-radius: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
import { Api, Get, Query, useContext } from "@midwayjs/hooks";
|
||||||
|
|
||||||
|
import { getVideoInfo } from "./utils/bili";
|
||||||
|
|
||||||
|
import { client } from "./utils/redis";
|
||||||
|
|
||||||
|
const availableStyle = ["gray", "white", "black", "shadow"];
|
||||||
|
|
||||||
|
export default Api(
|
||||||
|
Get(),
|
||||||
|
Query<{ av?: string, bv?: string }>(),
|
||||||
|
async () => {
|
||||||
|
const ctx = useContext();
|
||||||
|
|
||||||
|
const id = ctx.query.av || ctx.query.bv;
|
||||||
|
const type = "av" in ctx.query ? "av" : "bv" in ctx.query ? "bv" : undefined;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return "请输入 ID";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
return "无效的 type";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加使用数量
|
||||||
|
await client.incr("api-next:stat:bili");
|
||||||
|
|
||||||
|
// 尝试使用缓存
|
||||||
|
const cached = await client.lRange(`api-next:bili:${id}`, 0, 3);
|
||||||
|
|
||||||
|
let result;
|
||||||
|
|
||||||
|
if (cached.length) {
|
||||||
|
result = {
|
||||||
|
title: cached[0],
|
||||||
|
image: cached[1],
|
||||||
|
desc: cached[2],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const info = await getVideoInfo(id, type);
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
return "获取失败";
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.rPush(`api-next:bili:${id}`, [
|
||||||
|
info.title,
|
||||||
|
info.image,
|
||||||
|
info.desc,
|
||||||
|
]);
|
||||||
|
await client.expire(`api-next:bili:${id}`, 21600);
|
||||||
|
|
||||||
|
result = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后期参数填补
|
||||||
|
let classname = "bili-box";
|
||||||
|
|
||||||
|
if (ctx.query.style && availableStyle.includes(ctx.query.style)) {
|
||||||
|
classname += ` ${ctx.query.style}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = `https://www.bilibili.com/video/${type === "av" ? "av" : ""}/${id}`;
|
||||||
|
|
||||||
|
return (`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cmn-hans">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>哔哩小窗 iFrame API</title>
|
||||||
|
<meta name="referrer" content="no-referrer" />
|
||||||
|
<link href="/assets/bili.css" rel="stylesheet" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="${classname}">
|
||||||
|
<a class="bili-img" href="${link}" target="_blank">
|
||||||
|
<img src="${result.image}" alt="${result.title}" referrerpolicy="no-referrer" />
|
||||||
|
</a>
|
||||||
|
<div class="bili-info">
|
||||||
|
<h1><a href="${link}" target="_blank">${result.title}</a></h1>
|
||||||
|
<p>${result.desc}</p>
|
||||||
|
</div>
|
||||||
|
<div class="bili-powered">
|
||||||
|
<a href="https://api.paugram.com" target="_blank" title="使用了奇趣保罗的哔哩哔哩小窗接口">哔哩小窗</a>
|
||||||
|
</div>
|
||||||
|
<div class="bili-hidden">Cached: ${cached.length ? true : false}</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { Api, Get, Query, useContext } from "@midwayjs/hooks";
|
||||||
|
|
||||||
|
import { client } from "./utils/redis";
|
||||||
|
|
||||||
|
export default Api(
|
||||||
|
Get(),
|
||||||
|
Query<{ id?: string, loop?: string }>(),
|
||||||
|
async () => {
|
||||||
|
const ctx = useContext();
|
||||||
|
|
||||||
|
// 增加使用数量
|
||||||
|
await client.incr("api-next:stat:dji");
|
||||||
|
|
||||||
|
return (`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cmn-hans">
|
||||||
|
<head>
|
||||||
|
<title>大疆视频外链</title>
|
||||||
|
<meta name="referrer" content="no-referrer"/>
|
||||||
|
<style>*{ margin: 0 } video{ width: 100%; height: 100%; background: #000; max-width: 100%; outline: none }</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${ctx.query.id ? `<video src="https://cn-videos.dji.net/video_trans/${ctx.query.id}/720.mp4" controls${"loop" in ctx.query ? " loop" : ""}></video>` : "<p>没有输入 ID</p>"}
|
||||||
|
</body>
|
||||||
|
</html>`)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -14,9 +14,6 @@ export default Api(
|
||||||
ctx.set("access-control-allow-origin", "*");
|
ctx.set("access-control-allow-origin", "*");
|
||||||
ctx.set("access-control-allow-headers", "x-requested-with");
|
ctx.set("access-control-allow-headers", "x-requested-with");
|
||||||
|
|
||||||
// 增加使用数量
|
|
||||||
await client.incr("api-next:stat:netease");
|
|
||||||
|
|
||||||
const { id } = ctx.query;
|
const { id } = ctx.query;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
|
@ -26,6 +23,9 @@ export default Api(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 增加使用数量
|
||||||
|
await client.incr("api-next:stat:netease");
|
||||||
|
|
||||||
// 直接播放
|
// 直接播放
|
||||||
if ("play" in ctx.query) {
|
if ("play" in ctx.query) {
|
||||||
ctx.status = 302;
|
ctx.status = 302;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import fetch from "isomorphic-unfetch";
|
||||||
|
|
||||||
|
export const getVideoInfo = async (id: number | string, type: "av" | "bv") => {
|
||||||
|
return fetch(`https://api.bilibili.com/x/web-interface/view?${type === "av" ? "aid" : "bvid"}=${id}`).then(res => {
|
||||||
|
try{
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
// Todo: 这个地方可能会有问题
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}).then(json => {
|
||||||
|
return json ? parseVideoData(json.data) : undefined;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseVideoData = (json: any) => {
|
||||||
|
return {
|
||||||
|
title: json.title,
|
||||||
|
image: json.pic.replace(/^http:\/\//, "https://"),
|
||||||
|
desc: json.desc.length > 60 ? `${json.desc.substring(0, 60)}...` : json.desc,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue