vue-dplayer的安装
npm install vue-dplayer --save
在使用vue-dplayer开发视频播放器过程中,关于弹幕功能的问题需要解释一下
- <template>
- <div id="test">
- <vue-dplayer id="dplayer" ref="dplayerRef" class="dplayer" :options="options"></vue-dplayer>
- </div>
- </template>
-
- <script>
- import VueDPlayer from 'vue-dplayer'
-
- export default {
- components: {
- VueDPlayer
- },
- data() {
- return {
- options: {
- lang: "zh-cn",
- preload: 'auto',
- video: {
- type: 'auto',
- url: 'https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4'
- }
- }
- }
- },
- created() {
-
- },
- methods: {}
- }
-
- </script>
-
- <style>
- #test {
-
- }
-
- .dplayer {
- height: 400px;
- width: 800px;
- }
- </style>
这是一个非常干净,只有基础播放器功能的代码
前端展示效果如下

然后我们来看一下 DPlayer api 的接口文档地址https://dplayer.diygod.dev/zh/guide.html


所以options的内容被改为
- options: {
- lang: "zh-cn",
- preload: 'auto',
- video: {
- type: 'auto',
- url: 'https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4'
- },
- danmaku: true,
- apiBackend: {
- read (options) {
- console.log('Pretend to connect WebSocket');
- options.success([]);
- },
- send (options) {
- console.log('Pretend to send danmaku via WebSocket', options.data);
- options.success();
- },
- }
- }
结果前端报错:
TypeError: options.success is not a function
[Vue warn]: Error in mounted hook: "TypeError: options.success is not a function"
意思是没有options.success这个方法
怎么会没有呢,都是按照文档的步骤来的呢

输出这两条试试
read: undefinedv2/?id=undefined
send: undefinedv2/
其实看到这我就知道了,如果把官方给的danmaku.id 和 danmaku.api 加上去的话就能拼成一个完整的url
可就算这样也不能使用options.success()这个方法,没办法只能看源代码
DPlayer/blob/master/demo/demo.js
从这段demo.js代码中可以找到https://s-sh-17-dplayercdn.oss.dogecdn.com/1678963.json这个示例数据,大概是长这样子的
- {
- "code": 0,
- "data": [
- [
- 230.523,
- 0,
- 16777215,
- "618c713c",
- "键盘妹子挺好看?"
- ],
- [
- 25.837,
- 0,
- 16777215,
- "6b2884ac",
- "Goose house炒鸡棒!!! 银之匙种草他们组合"
- ],
- [
- 235.243,
- 1,
- 16707842,
- "929815d3",
- "刚才说比其他翻唱都好听的你是认真的么,这。就是原唱"
- ],
- ...
- ]
- }
为什么是长这个样子的呢?我后面再讲,咱们先继续往下看
找到被作者注释掉的read 和 send方法,看看作者是怎么写的
原来传了不止一条数据,我就奇怪了为什么options.success()这方法找不到
我们在read方法中用 console .log('callback: ' + callback); 看看callback有什么
- callback: function (s, r) {
- if (++a, s)
- s.response ? n.options.error(s.response.msg) : n.options.error("Request was unsuccessful: " + s.status), i[o] = [];
- else {
- var l = ["right", "top", "bottom"];
- i[o] = r ? r.map(function (e) {
- return {
- time: e[0],
- type: l[e[1]],
- color: e[2],
- author: e[3],
- text: e[4]
- };
- }) : [];
- }
- if (a === e.length)
- return t(i);
- }
拿 [230.523, 0, 16777215, "618c713c", "键盘妹子挺好看?"] 这条数据来看的话,相当于
- {
- time: 230.523,
- type: "right",
- color: "#fff",
- author: "618c713c",
- text: "键盘妹子挺好看?"
- }
其中color需要将10进制转成16进制
文档中有给出danmaku.id danmaku.api这两条数据给我们使用,但是实际上作者会给你的api上加条非常诡异的后缀 v2/?id=,控制台能看到他调用api接口,但是弹幕就是加载不上去。
解决办法
我们不能使用作者提供的danmaku.id danmaku.api,需要自己覆写read send方法
- import {getDanmuList, addDanmu} from '@/api/video/videoDanmu'
-
- options: {
- lang: "zh-cn",
- preload: 'auto',
- video: {
- type: 'auto',
- url: 'https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4'
- },
- danmaku: true,
- apiBackend: {
- send: (endpoint, danmakuData, callback) => {
- const danmu = {
- color: danmakuData.color,
- type: danmakuData.type === 'right' ? 0 : danmakuData.type === 'top' ? 1 : 2,
- text: danmakuData.text,
- time: danmakuData.time
- }
- addDanmu(danmu).then((response) => {
- this.$notify({
- title: '弹幕发送成功',
- message: danmu.text,
- type: 'success'
- });
- callback();
- }).catch((error) => {
- this.$notify.error({
- title: '失败',
- message: '弹幕发送失败 ' + error,
- });
- })
- },
- read: (endpoint, callback) => {
- getDanmuList(this.video.id).then((response) => {
- if (!response || response.code !== 0) {
- endpoint.error && endpoint.error(response && response.msg);
- return;
- }
- callback('', response.data);
- }).catch((e) => {
- console.error(e);
- endpoint.error && endpoint.error();
- });
- }
- }
- }
send方法中的danmakuData参数就是用户填写的弹幕信息,大概就是这样的json数据
- {
- "color": "#fff",
- "type": 0,
- "text": "123",
- "time": 0
- }
可以选择自己重新包装一层,看你要设计成什么样的 数据结构 。最后一定要调用callback()方法将发送弹幕的对话框关闭掉
read方法要注意一下,因为作者设计的接口数据格式非常逆天,在调用了自己的后端接口获取到弹幕数据之后,一定要改成这样格式的数据
- [
- [
- "5.713021",
- 0,
- "#fff",
- "c3cad6e5",
- "嗨哈嗨"
- ],
- [
- "2.572623",
- 0,
- "#fff",
- "c3cad6e5",
- "嗨嗨嗨"
- ],
- ...
- ]
然后像这样子callback('', response. data )塞到播放器里面就可以发送弹幕了

这是我的个人博客,里面有很多经典案例,感兴趣的可以一起来学习 blog.qxbase.com