Vue3 实现 B 站视频站外播放器:输入 URL 自动解析为 player.bilibili.com


湖山客
原创
发布时间: 2026-02-06 16:10:26 | 阅读数 0收藏数 0评论数 0
封面
本文将带你使用 Vue3 实现一个 B 站视频站外播放器组件:只需输入一个普通的 Bilibili 视频链接,即可自动解析 BV 号与分页参数,并生成可嵌入的 player.bilibili.com 外链播放器。教程涵盖 URL 解析逻辑、参数校验、安全 iframe 嵌入方式以及组件封装思路,适合想提升前端工程能力与实战经验的开发者阅读。通过这个小工具,你将掌握如何把真实业务需求拆解为可维护的 Vue 组件,并理解浏览器 URL API 在实际项目中的应用。
1

官方内容

https://player.bilibili.com/ 如图所示这个是相关的文档就是有点简陋


站外(外链)播放器使用文档

引用地址

https://player.bilibili.com/player.html

使用示例

<iframe src="//player.bilibili.com/player.html?bvid=BV1B7411m7LV" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>


查询字符串参数

boolean类型,在QueryString中可以使用01表示。


参数名

类型

需要

说明

援助

number


UGC 视频 ID。aid、bvid 选择其一即可

cid

number


UGC 视频 ID

bvid

string

UGC 视频 ID。aid、bvid 选择其一即可

seasonId

number


OGV 视频 ID

剧集ID

number

OGV 视频ID。优先级为aid、bvid

海报

boolean


展示封面

自动播放

boolean


自动播放

静音

boolean


静音

t

number


跳转到媒体的首要时间点,单位:秒

弹幕

boolean


false表示关闭弹幕,其他表示默认值

种类

number


群组类型。非通用业务需要此参数

参考

boolean


跳链时携带当前的Referrer。用于合作方查询来自嵌入网站的跳转次数

p

number


多 P 视频的集数。从 1 开始统计,若有 cid 参数,则此参数不生效



2

内嵌使用

  1. 首先我们新建一个基本的html项目 如图1所示
  2. 代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div style="width: 80%; aspect-ratio: 16 / 9; border: 1px solid;">
<iframe width="100%" height="100%" src="//player.bilibili.com/player.html?bvid=BV1B7411m7LV&danmaku=true&poster=true&autoplay=false" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>
</div>

</body>
</html>


3

解析网址方式介绍

如视频讲解 我们接下来要做的就是把

https://www.bilibili.com/video/BV1hj6BB4Eh4/?spm_id_from=333.1007.tianma.1-1-1.click

解析为

<iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115983612123221&bvid=BV1hj6BB4Eh4&cid=35709586164&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>
4

正则表达式

测试效果如图所示

BV[0-9A-Za-z]+


BV:这表示匹配必须以大写的 "B" 和 "V" 两个字母开头。因为 B 站视频 ID 都是 BV 开头的。

[0-9A-Za-z]:这是一个字符集,表示紧跟在 BV 后面的字符可以是:

  1. 0-9:任何数字
  2. A-Z:任何大写字母
  3. a-z:任何小写字母

+:这是一个量词,表示前面的字符集(即数字或字母)必须出现 1 次或多次

5

输入链接解析外链

代码如下 流程是我们输入链接 然后点击确定触发方法, 然后判断是否为哔哩哔哩的路径 判断是否有BV的参数,大家这里判断也可以自行修改比如判断是不是https开头的之类的 然后获取分页参数即可 代码如下


<template>
<div class="bili-parser">
<div class="input-wrapper">
<input
v-model.trim="inputUrl"
placeholder="粘贴 B 站链接,例如:https://www.bilibili.com/video/BVxxxx"
class="url-input"
@keyup.enter="handleEmbed"
/>
<button class="confirm-btn" @click="handleEmbed">确定</button>
</div>

<div v-if="bilibiliUrl" class="player-box">
<div class="iframe-container">
<iframe
:src="bilibiliUrl"
allowfullscreen
referrerpolicy="no-referrer"
sandbox="allow-scripts allow-same-origin allow-popups"
/>
</div>
<div class="info-bar">
<span>解析结果:<code>{{ bilibiliUrl }}</code></span>
</div>
</div>
</div>
</template>

<script setup>
import { ref } from 'vue';

const inputUrl = ref('');
const bilibiliUrl = ref('');

/**
* 解析逻辑
*/
function parseBili(url) {
if (!url) return null;

// 严格路径校验:必须包含 bilibili.com/video/
if (!url.includes('bilibili.com/video/')) {
return null;
}

// 提取 BV 号 (使用你指定的正则逻辑)
const bvMatch = url.match(/BV[0-9A-Za-z]+/);
if (!bvMatch) return null;
const bvid = bvMatch[0];

// 提取 分页p 参数 (不使用 try-catch)
let page = null;

// 补齐协议头,确保 URL 构造器不会报错
const safeUrl = url.startsWith('http') ? url : `https://${url.startsWith('//') ? url.substring(2) : url}`;

// 只有字符串包含点号(合法域名特征)且包含问号时才解析参数
if (safeUrl.includes('.') && safeUrl.includes('?')) {
const urlObj = new URL(safeUrl);
const p = urlObj.searchParams.get('p');

// 验证 p 是否为有效数字
if (p && !isNaN(p)) {
page = p;
}
}

return { bvid, page };
}

/**
* 点击确定或回车触发
*/
const handleEmbed = () => {
const result = parseBili(inputUrl.value);

if (!result) {
bilibiliUrl.value = '';
alert('请输入正确的 B 站视频链接(需包含 bilibili.com/video/)');
return;
}

const { bvid, page } = result;

// 使用 URL 对象构建嵌入链接
const embed = new URL('https://player.bilibili.com/player.html');
embed.searchParams.set('bvid', bvid);

// 核心逻辑:只有 page 存在时,才向 URLSearchParams 添加 p
if (page) {
embed.searchParams.set('p', page);
}

bilibiliUrl.value = embed.toString();
};
</script>

<style scoped>
.bili-parser {
max-width: 900px;
margin: 40px auto;
padding: 0 20px;
}

.input-wrapper {
display: flex;
gap: 12px;
margin-bottom: 24px;
}

.url-input {
flex: 1;
padding: 12px 16px;
border: 2px solid #e3e5e7;
border-radius: 10px;
font-size: 14px;
outline: none;
transition: border-color 0.2s;
}

.url-input:focus {
border-color: #00aeec;
}

.confirm-btn {
padding: 0 28px;
background: #00aeec;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
font-weight: 600;
}

.player-box {
background: #000;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
}

.iframe-container {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 */
}

.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}

.info-bar {
padding: 12px 16px;
background: #18191c;
color: #9499a0;
font-size: 12px;
border-top: 1px solid #2f3134;
}

.info-bar code {
color: #00aeec;
margin-left: 8px;
}
</style>


6

演示

演示效果看视频 完整代码在上一步

阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载
pdf下载 举报