点播直播弹幕实现1

点播弹幕实现

简要说明

之前突然觉得弹幕视频还挺有意思的,就想自己也实现点播弹幕和直播弹幕。由于是主学后端的,对于自己手动实现前端的弹幕功能感到困难,于是上网搜索有没有相关实现,首先找到了** CommentCoreLibrary**项目,不过貌似只能全局script导入,没有实现相应模块化,而我前端用的是vue3+ts,用起来感觉很难受,遂放弃。又经过一番搜寻,找到了 **DPlayer**项目,看了它的文档,正如它开头的一句🍭 Wow, such a lovely HTML5 danmaku video player,首先实现了一个功能很完善的播放器,同时也支持定制化改造,完美超出我的预期。OK!找到这个项目后我已经完全编写代码就绪了,给项目起个名Zplay,开写。

后来发现西瓜播放器也很好。

使用的技术

前端: vite+vue3+ts

记得上一次写前端是vue-cli+vue2,而上上次就是学习三件套+Jquery,还没怎么用,每次写前端代码都会学不少新东西,有点大跃进,感觉花里胡哨的是做不出来的,不过普普通通的还是没问题的,毕竟还有一堆现成的。

后端: SpringBoot+Mybatis-Plus

前后端接口

后端与数据库接口:

DROP DATABASE IF EXISTS `zplay`;
CREATE DATABASE `zplay` CHARACTER SET 'utf8mb4';

USE zplay;
CREATE TABLE danmaku(
	`id` INT UNSIGNED AUTO_INCREMENT,
	`barrage_type` TINYINT  NOT NULL COMMENT "弹幕类型",
	`time` DOUBLE NOT NULL COMMENT "弹幕时间",
	`color` INT UNSIGNED NOT NULL DEFAULT 16777215 COMMENT "颜色16进制数", 
	`content` VARCHAR(50) NOT NULL,
	`author` VARCHAR(20) NOT NULL,
	`video_id` INT NOT NULL,
	`gmt_create` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
	 PRIMARY KEY (`id`),
	 KEY `idx_video_id`(`video_id`)
)ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8mb4;

后端实体类兼DTO

注解是Mybatis-Plus的注解:

@TableName("danmaku")
@Data
public class Barrage {

    @TableId(value = "id",type = IdType.AUTO)
    private Long id;

    @TableField("barrage_type")
    private Byte barrageType;

    @TableField("time")
    private Double time;

    @TableField("color")
    private Long color;

    @TableField("content")
    private String content;

    @TableField("author")
    private String author;

    @TableField("video_id")
    private Long videoId;

    @TableField("gmt_create")
    private Date createTime;

    @TableField(exist = false) //直播时标识客户端的属性
    private String sign;
	
}

后端响应简易封装

code,msg规范起来的话或许用枚举类实现。

@Data
public class Result<T> {
    private Integer code;
    private String msg;
    private T data;

    public Result() {
    }

    public Result(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <E> Result<E> ok(E data) {
        return new Result<E>(200,"successful",data);
    }

    public  static <E> Result<E> fail(E data) {
        return new Result<E>(100,"fail",data);
    }
}

前端相应接口:

有一些和Dplayerts声明指定的类型不同,比如id,color,不过有需要可以先转换为any就可以了,主要刚开始没注意,color是16进制数代表的颜色。

export interface Barrage {
    id?: Number,
    barrageType: Number,
    time: Number,
    color: Number,
    content: string,
    author: string,
    videoId: Number,
    createTime?: Date,
    sign?: string
}

export interface DplayerBarrage {
    type: Number,
    time: Number,
    color: Number,
    text: string,
    author: string
}

前端实现

查看了Dplayer文档,实现弹幕功能只需要创建Dplayer时重写apiBackend即可,同时提供danmaku属性即可拥有发弹幕的组件,另外url其实可以随便指定,只要在apibackend中使用自己的url就可以了,另外Dplayer含支持MSE扩展,这里我使用了flv.js,于是代码如下:

function loadPlayer(videoInfo: VideoInfo) {
  const dp = new DPlayer({
    container: document.getElementById("video-player"),
    video: {
      url: videoInfo.url,
      type: "customFlv",
      customType: {
        customFlv: function (video: HTMLMediaElement, player: any) {
            const flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url: video.src,
            });
            flvPlayer.attachMediaElement(video);
            flvPlayer.load();
        },
      },
    },
    danmaku: {
      id: String(videoInfo.id),
      api: "http://127.0.0.1:3000/danmu",
    },
    apiBackend: {
      read: (options)=> {
        getBarrages(videoInfo.id).then((res)=>{
          const danmus: Array<DplayerBarrage> = res.data.map(item=>{
            return {
                  type: item.barrageType,
                  time: item.time,
                  color: item.color,
                  text: item.content,
                  author: item.author
            }
          })
          options.success(danmus);
          console.log(danmus);
        }).catch((e)=>{
          console.error(e);
          options.error && options.error();
        })
      },
      send: (options)=>{
        const danmu = options.data;
        const barrage: Barrage = {
          barrageType: danmu.type,
          content: danmu.text,
          time: danmu.time,
          color: danmu.color,
          author: danmu.author,
          videoId: danmu.id
        }
        sendBarrage(barrage).then((res)=>{
          options.success && options.success(res.data)
        }).catch((e)=>{
          console.error(e);
          options.error && options.error();
        })
      }
    }
  });
}

至于其中的options,是阅读了Dplayer源码得到的,发收弹幕实际上都是调用了源码中danmaku.js中的方法,并传参options调用api,阅读源码可查看细节参数。

后端实现

后端实现还是比较简单的,读取弹幕根据videoId获取相应弹幕返回即可,发送弹幕把弹幕存入数据库即可,没什么坑点。

跨域设置

自己调试的时候,因为前后端使用的是不同端口,所以也需要设置跨域。SpringBoot有两种常见的设置跨域的方法。一个是写配置类实现WebMvcConfigurer接口,一个是写拦截器 ,这里采用第一种。

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("GET","POST")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedOriginPatterns("*")
                .maxAge(3600);
    }
}

杂项

1.设置"@"路径别名

vite.config.ts中的配置:

  resolve: { 
    alias: { 
      '@': resolve(__dirname, './src'), 
     },
  }

tsconfig中配置:

    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值