vue3 直播弹幕 用法 内容只是参考请根据实际开发

1、安装 video.js 和 videojs-contrib-hls 插件:

npm install video.js --save
vue3 暂时用不了
// npm install videojs-contrib-hls  --save
// npm install @videojs/http-streaming  --save

2、需要加载视频的页面

<template>
  <div class="Camera" v-if="Camera">
    <!-- id属性一定要配置,因为js初始化video.js 实例时,
    会和这个dom进行绑定。通过video.js实例对象,来控制这个视频播放器。-->
    <video
      ref="video"
      id="video"
      class="video-js vjs-default-skin"
      controls
      width="400px"
      height="400px"
      object-fit:cover
      preload="auto">
     <source :src="videoUrl" type="application/x-mpegURL">
   </video>
  </div>
</template>

3.引入文件

<sctript>
import videojs from 'video.js' //是播放多种直播流类型的播放插件
  import 'video.js/dist/video-js.min.css

vue3暂时用不了
  // import 'videojs-contrib-hls' //负责播放 m3u8 格式的直播数据的插件,和viedeo.js搭配使用
  // import "@videojs/http-streaming"//video.js获取直播流的插件, 和video.js搭配使用

</script>

 4.直播

//1 声明 videoUrl 变量,保存 .m3u8 直播地址
const videoUrl = ref(“”);
let player = null;

//页面关闭 卸载组件
onUnmounted(()=>{
  //当前组件被卸载的时候,要把播放器对象 player 也删除,
  // 否则当前组件被卸载,但是 player播放器对象却没有被卸载,
  // 导致下一次进入播放页面时,无法正常播放
  player.dispose();
  
})

//进入页面 注册组件 需要用到声明周期
onMounted(()=>{
  //获取直播间地址
  getRealLive_Douyu(id,false,2,(liveUrl)=>{
    //2.获取直播间链接地址,并赋值给videoUrl
    vidoUrl.value = liveUrl;
    
    //nextTick 页面加载完毕在加载里面内容
    nextTick(()=>{
      //3.当 videoUrl.value 直播地址所在的dom video 更新完毕之后,在实例化
      // video.js 对象
      //video("参数":是dom的id属性值,{配置})
      player = videojs("video",{
        autoplay:true,//true , 浏览器准备好开始播放
        muted:false,//静音模式
        loop:true,//导致视频一结束就重新开始
        controls:true,//显示播放器
        preload:"auto",//auto 浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
        language:'zh-CN',//汉化
        bigPlayButton:false,//播放器中的播放按钮
        controlBar:true,//显示视频控件
        notSupportedMessage:'此视频暂无播放,请稍后再试'
      })
    })
  })
})

 5.直播弹幕

需要用到 websocket:双向通讯协议,一旦客户端和服务器建立链接,客户端可以给服务器发送消息,服务器也可以主动给客户端发消息。这个链接是长链接,一定时间不会断开。像斗鱼弹幕服务器约定45s断开;连接。防止两端断开链接,需要定时发送心跳包信息,只能客户端向服务器发送消息,服务器响应完数据以后,就断开链接了,是短连接

let timer = null;
//1.创建 websocket 对象 
const ws = new WebSocket("wss://danmuproxy.douyu.com:8505/")
//2.监听 open 方法, 表示链接成功
ws.onopen = ()=>{
  console.log("链接成功");
  //获取弹幕流程
  //2.1先向服务器发送登录的消息 (可参考斗鱼开发平台弹幕接口)
  ws.send(
    //必需要转为二进制
    toBuffer(
      `type@=loginreq/roomid@=${id}/username@=visitor7102488/
    uid@=1198284824/
    ver@=20190610/aver@=218101901/ct@=0/dfl@=/\0`
      )
    );
    // 2.2 登录成功,在发送进入房间弹幕频道的消息给服务器
    ws.send(toBuffer(`type@=joingroup/rid@=${id}/gid@=1/\0`));
    //2.3 45s 心跳信息
    timer = setInterval(()=>{
      ws.send(toBuffer(`type@=mrkl/\0`));
    },45000);
};

//3.监听 onmessage 方法,接收服务器数据
const danmulists = reactive([]);
const danmDom = ref(null);
ws.onmessage = async(data)=>{
  //获取Blod的值,需要把二进制转为字符串
  const text = await new Response(data.data).text();
  console.log(text);
  //3.1 从 text 中提取type的值,判断消息类型:uenter是新进直播间。chatmsg是弹幕消息
  //.*?指的是任意字符 , 一直匹配到“/” 为止
  const type = text.match(/tayp@=.*?\//)[0];
  if(type.includes('uenter')){
    //新进用户
    let nn = text.match(/nn@=.*?\//)[0].split('=').replace('/','');
    danmulists.push({
      nn,
      type:'uenter'
    });
  }else if(type.includes('chatmsg')){
    //弹幕消息
    let nn = text.match(/nn@=.*?\//)[0].split('=')[1].replace('/','');
    let txt = text..match(/text@=.*?\//)[0].split('=')[1].replace('/','');
    danmulists.push({
      nn,
      txt,
      type:'chatmsg'
    });
  }
}
//4. 监听onclose方法,客户端服务器断开链接
ws.onclose = ()=>{
  console.log('服务器断开');
}
//5.onerror 监听服务器异常
ws.onerror = ()=>{
  console.log('服务器异常')
}

//页面关闭 卸载组件
onUnmounted(()=>{
  clearInterval(timer);
  ws.close();
})

最后全部代码部分

1.HTML部分

<template>
    <!-- id 属性一定要配置,因为js初始化videojs实例时,会和这个dom进行绑定。通过video js 实例对象,来控制这个视频播放器 -->
    <video
      v-if="videoUrl"
      ref="video"
      id="video"
      class="video-js vjs-default-skin"
      controls
      width="100vw"
      height="400px"
      object-fit:cover
      preload="auto"
    >
      <source :src="videoUrl" type="application/x-mpegURL" />
    </video>
    <div class="danmu" ref="danmDom">
      <div v-for="(danmu, index) in danmulists" :key="index">
        <p v-if="danmu.type == 'uenter'" class="greet">
          欢迎<span class="name1">{{ danmu.nn }}</span>
        </p>
        <p v-if="danmu.type == 'chatmsg'" class="news">
          <span class="name2">{{ danmu.nn }}:</span><span class="txt">{{ danmu.txt }}</span>
        </p>
      </div>
    </div>
  </div>
</template>

 2.JavaScript部分

<script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
//目标路由组件通过vue-router ;路由组合式api
import getRealLive_Douyu from '@/assets/斗鱼sign签名参数计算';
import toBuffer from '@/assets/斗鱼弹幕数据转换';
import { useRoute } from 'vue-router';
import videojs from 'video.js'; //是播放多种直播流类型的播放器插件
/* import 'videojs-contrib-hls'; //负责播放 m3u8 格式的直播数据插件,和videojs使用
import '@videojs/http-streaming'; //videojs获取直播流的插件*/
import 'video.js/dist/video-js.min.css';

const route = useRoute(); //返回值route是一个响应式对象Proxy,因此它也可以用watch监听。
const id = route.query.id; // 获取直播间id
// const data = await http(`/live/${id}/index.pageContext.json`);

//1.声明 videoUrl 变量,保存 .m3u8直播地址
const videoUrl = ref('');

let player = null;
let timer = null;

//卸载 组件
onUnmounted(() => {
  //当前组件被卸载的时候,要把播放器对象 player 也删除,否则当前组件被卸载,但是 player 播放器对象却没有被卸载,导致下一次进入播放页面的时候,无法正常播放
  player.dispose();
  clearInterval(timer);
  ws.close();
});

//注册组件
onMounted(() => {
  //获取直播间链接地址。
  getRealLive_Douyu(id, false, 2, (liveUrl) => {
    //2.获取直播间链接地址,并赋值给videoUrl
    videoUrl.value = liveUrl;
    nextTick(() => {
      //3.当 videoUrl.value 直播地址所在的dom video 更新完毕之后,在实例化vido.js 对象
      //videojs("参数1":是dom的id属性值,{配置})
      player = videojs('video', {
        autoplay: true, //true,浏览器准备好时开始播放。
        muted: false, //静音模式
        loop: true, //导致视频一结束就重新开始。
        controls: true, //显示播放器
        preload: 'auto', //auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
        language: 'zh-CN', //汉化
        fluid: true, //当true时,
        bigPlayButton: false, //播放器中的播放按钮
        controlBar: true, //显示视频控件
        notSupportedMessage: '此视频暂无法播放,请稍后再试'
      });
    });
  });
});

//websocket:双向通讯协议,一旦客户端和服务器建立链接,客户端可以给服务器发送消息,服务器也可以主动给客户端发消息。这个链接是长链接,一定时间内不会断开。像斗鱼弹幕服务器约定45s断开链接。防止两端断开链接,需要定时发送心跳包消息,只能客服端向服务器发送消息,服务器响应完数据以后,就断开链接了。是短链接,

//1.创建websocket对象
const ws = new WebSocket('wss://danmuproxy.douyu.com:8505/');
//2.监听open方法,表示链接成功
ws.onopen = () => {
  console.log('链接成功');
  //获取弹幕数据流程
  //2.1先向服务器发送登录的消息
  ws.send(
    toBuffer(
      `type@=loginreq/roomid@=${id}/username@=visitor7102488/uid@=1198284824/ver@=20190610/aver@=218101901/ct@=0/dfl@=/\0`
    )
  );
  //2.2登录成功,在发送进入房间弹幕频道的消息给服务器
  ws.send(toBuffer(`type@=joingroup/rid@=${id}/gid@=1/\0`));
  //2.3 45s心跳消息
  timer = setInterval(() => {
    ws.send(toBuffer(`type@=mrkl/\0`));
  }, 45000);
};
//3. 监听 onmessage方法,接收服务器的数据
const danmulists = reactive([]);
const danmDom = ref(null);
ws.onmessage = async (data) => {
  //获取Blod的值
  const text = await new Response(data.data).text();
  console.log(text);
  //3.1 从text 中提取type的值,判断消息类型:uenter是新进直播间。chatmsg是弹幕消息
  const type = text.match(/type@=(.*?)\//)[0];

  if (type.includes('uenter')) {
    //新进用户
    let nn = text
      .match(/nn@=.*?\//)[0]
      .split('=')[1]
      .replace('/', '');
    danmulists.push({
      nn,
      type: 'uenter'
    });
  } else if (type.includes('chatmsg')) {
    //是弹幕消息
    let nn = text
      .match(/nn@=.*?\//)[0]
      .split('=')[1]
      .replace('/', '');
    let txt = text
      .match(/txt@=.*?\//)[0]
      .split('=')[1]
      .replace('/', '');
    danmulists.push({
      nn,
      txt,
      type: 'chatmsg'
    });
  }
  //3.2 当弹幕列表可以滚动的时候,让弹幕div自动滚动到底部
  danmDom.value.scrollTop = danmDom.value.scrollHeight - danmDom.value.clientHeight;
};
//4. 监听onclose方法,客户端服务器断开链接
//5. onerror,监听服务器一次
ws.onerror = () => {
  console.log('服务器异常');
};
</script>

3. CSS部分

<style lang="less" scoped>
*{
  margin: 0;
  padding: 0;
}

.live {
  background-color: #181315;
  height: 98vh;
}
.danmu {
  height: 67%;
  overflow-y: scroll;
  p{
    background-color: rgba(0, 0, 0, 0.5);
  }
  .greet {
    font-size: 3.46667vw;
    font-weight: 400;
    margin: 0.8vw 0;
    padding: 0.8vw 2.13333vw;
    word-wrap: break-word;
    border-radius: 2.66667vw;
    max-width: 75.33333vw;
    color: #fff;
    .name1 {
      color: #ff921c;
      margin-left: 1.33333vw;
      opacity: 1;
    }
  }
  .news {
    font-size: 3.46667vw;
    margin: 0.8vw 0;
    padding: 0.8vw 2.13333vw;
    word-wrap: break-word;
    border-radius: 2.66667vw;
    max-width: 75.33333vw;
    width: -moz-fit-content;
    width: fit-content;
    word-break: break-all;
    color: #fff;
    .name2 {
      color: #999;
    }
    .txt {
      padding-left: 2vw;
    }
  }
}
</style>

 运行结果

注:由于一些直播类开放平台不支持个体验用户注册 无法正常获取直播或弹幕 此文章只提供参考。

  • 24
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3视频播放器可拖动打点评论弹幕的实现可以分为几个步骤: 1. 创建视频播放器组件:首先,你需要创建一个Vue组件来实现视频播放器的功能。你可以使用Vue的官方视频播放器插件,如vue-video-player或者video.js,或者自己编写一个自定义的播放器组件。 2. 添加弹幕功能:在视频播放器组件中,你可以添加一个弹幕层,用于显示用户的评论弹幕。可以使用CSS来控制弹幕层的样式和位置。 3. 实现弹幕拖动:为了实现弹幕的拖动功能,你需要监听用户的鼠标事件(mousedown、mousemove、mouseup)或者触摸事件(touchstart、touchmove、touchend),来获取用户的操作信息。根据用户的操作,你可以改变弹幕的位置。可以使用Vue的指令来绑定事件监听器,或者直接在组件的方法中编写事件处理逻辑。 4. 打点评论功能:你可以在视频播放器组件中添加一个打点评论的功能,用于让用户在指定的时间点添加评论。可以使用Vue的计算属性来获取视频的当前时间,并且监听时间变化,当用户点击打点评论按钮时,将评论信息添加到对应的时间点上。 总结起来,实现Vue3视频播放器可拖动打点评论弹幕的步骤包括创建视频播放器组件、添加弹幕功能、实现弹幕拖动、以及打点评论功能。通过监听用户的操作和视频的播放时间,你可以实现弹幕的拖动和打点评论的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值