vue+node 实现视频在线播放的实例代码


Posted in Javascript onOctober 19, 2020

1.node服务端

数据流传输,可在线缓存

//获取参数
  var params=urldeal.parse(req.url,true).query
  const ROOT_PATH = process.cwd();//必须使用绝对路径,使用相对路径会直接下载文件
  let path =ROOT_PATH+params.url;

  let stat = fs.statSync(path); //获取文件信息
  let fileSize = stat.size;
  let range = req.headers.range;

  if (range) {
    //有range头才使用206状态码

    let parts = range.replace(/bytes=/, "").split("-");
    let start = parseInt(parts[0], 10);
    let end = parts[1] ? parseInt(parts[1], 10) : start + 9999999;

    // end 在最后取值为 fileSize - 1
    end = end > fileSize - 1 ? fileSize - 1 : end;

    let chunksize = (end - start) + 1;
    let file = fs.createReadStream(path, { start, end });
    let head = {
      'Content-Range': `bytes ${start}-${end}/${fileSize}`,
      'Accept-Ranges': 'bytes',
      'Content-Length': chunksize,
      'Content-Type': 'video/mp4',
    };
    res.writeHead(206, head);
    file.pipe(res);     //Node中的Server端HTTP response是Writable流
  } else {
    let head = {
      'Content-Length': fileSize,
      'Content-Type': 'video/mp4',
    };
    res.writeHead(200, head);
    fs.createReadStream(path).pipe(res);
  }

2.vue客户端

1.安装video-player插件

cnpm install vue-video-player --save

2.组件中引用

<video-player class="video-player vjs-custom-skin"
         ref="videoPlayer"
         :playsinline="true"
         :options="playerOptions"
 ></video-player>

3.调用的data中的数据

data() {
  return {
   // 视频播放
   playerOptions: {
    playbackRates: [0.5, 1.0, 1.5, 2.0], //播放速度
    autoplay: false, //如果true,浏览器准备好时开始回放。
    muted: false, // 默认情况下将会消除任何音频。
    loop: false, // 导致视频一结束就重新开始。
    preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
    language: 'zh-CN',
    aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
    fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
    sources: [{
     type: "",
     //src: require('@/assets/'+this.vurl)//url地址
      src: 'http://localhost:10086/videos?url=/public/videos/'+this.vurl, //url地址,请求中需要包含具体的视频文件名
    }],
    poster: '', //你的封面地址
    // width: document.documentElement.clientWidth,
    notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
    controlBar: {
     timeDivider: true,
     durationDisplay: true,
     remainingTimeDisplay: false,
     fullscreenToggle: true //全屏按钮
    }
   }
  }
 },

附录:vue+flvjs播放直播流FLV,分页时如何断开之前直播流解决办法

使用flvjs库同时播放flv文件,需要分页发现,之前直播流没有断开,很影响性能,网上查阅借鉴下边代码实现断开上页直播流

// 销毁播放器实例
  closePlayer() {
   if (this.player.length > 0) {
    this.player.forEach((item) => {
     item.destroy(true);
     item.off('ended', function () {});
     item.off('error', function () {});
     item = null;
    });
    this.player = [];
   }
  },
// 初始化播放器
  initPlayer(id, url, img) {
   let doms = document.getElementById(id);
   doms.innerHTML = '';
   this.player.push(
    new FlvPlayer({
     id: id,
     url: url,
     poster: img,
     isLive: true,
     autoplay: true,
     volume: id == 'videos0' ? 0.5 : 0,
     preloadTime: 10,
     minCachedTime: 5,
     cors: true,
    })
   );
   this.player[this.player.length - 1].on('ended', () => {
    //事件名称可以在上述查询
    this.getLivingList();
   });
   this.player[this.player.length - 1].on('error', () => {
    //事件名称可以在上述查询
    this.getLivingList();
   });
  },
// 翻页操作
  currentChange(e) {
   this.closePlayer();
   this.pageno = e;
   this.getLivingList();
  },
  // 获取直播中的列表
  async getLivingList() {
   let res = await this.$req(api.liveShowers, {
    ...this.searchForm,
    pageno: this.pageno - 1,
    pagesize: this.pagesize,
   });
   console.log(res);
   if (res.code == 200) {
    // 获取到数据,赋值然后循环实例化
    res.data.showers.push(res.data.showers[0]);
    res.data.showers.push(res.data.showers[0]);
    res.data.showers.push(res.data.showers[0]);
    res.data.showers.push(res.data.showers[0]);
    this.livingList = res.data.showers;
    this.totalP = res.data.total_page - 0;
    this.totalS = res.data.total_showers;
    this.isrefresh = false;
    if (this.livingList.length > 0) {
     setTimeout(() => {
      this.livingList.forEach((item, idx) => {
       let domid = 'videos' + idx;
       this.initPlayer(
        domid,
        item.play_url,
        this.$store.state.coverTop + item.showcover
       );
      });
     }, 400);
    } else {
     // 如果返回没有直播数据又不是第一页。就跳到第一页再请求一下
     if (this.pageno > 1) {
      this.pageno = 1;
      this.getLivingList();
     }
    }
   }
  },

总结

到此这篇关于vue+node 实现视频在线播放的实例代码的文章就介绍到这了,更多相关vue视频在线播放内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
node.js中的定时器nextTick()和setImmediate()区别分析
Nov 26 Javascript
JavaScript限定图片显示大小的方法
Mar 11 Javascript
jQuery动态效果显示人物结构关系图的方法
May 07 Javascript
angularjs创建弹出框实现拖动效果
Aug 25 Javascript
实例讲解js验证表单项是否为空的方法
Jan 09 Javascript
html、css和jquery相结合实现简单的进度条效果实例代码
Oct 24 Javascript
在网页中插入百度地图的步骤详解
Dec 02 Javascript
js删除数组中的元素delete和splice的区别详解
Feb 03 Javascript
浅谈Vue路由快照实现思路及其问题
Jun 07 Javascript
React组件内事件传参实现tab切换的示例代码
Jul 04 Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
Apr 19 Javascript
微信小程序如何访问公众号文章
Jul 08 Javascript
js实现网页随机验证码
Oct 19 #Javascript
JS实现4位随机验证码
Oct 19 #Javascript
如何编写一个 Webpack Loader的实现
Oct 18 #Javascript
JavaScript中EventBus实现对象之间通信
Oct 18 #Javascript
vuex刷新后数据丢失的解决方法
Oct 18 #Javascript
JavaScript大数相加相乘的实现方法实例
Oct 18 #Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
Oct 18 #Javascript
You might like
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
用PHP调用数据库的存贮过程
2006/10/09 PHP
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
PHP实现QQ登录实例代码
2016/01/14 PHP
Smarty日期时间操作方法示例
2016/11/15 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
toString()一个会自动调用的方法
2010/02/08 Javascript
js拼接html注意问题示例探讨
2014/07/14 Javascript
Node.js 的异步 IO 性能探讨
2014/10/08 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
JavaScript中计算网页中某个元素的位置
2015/06/10 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
nodejs 实现钉钉ISV接入的加密解密方法
2017/01/16 NodeJs
利用Angular.js编写公共提示模块的方法教程
2017/05/28 Javascript
如何对react hooks进行单元测试的方法
2019/08/14 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
[02:47]2018年度DOTA2最佳辅助位选手4号位-完美盛典
2018/12/17 DOTA
详细解读Python中的__init__()方法
2015/05/02 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
Python中运算符&quot;==&quot;和&quot;is&quot;的详解
2016/10/08 Python
Python利用itchat对微信中好友数据实现简单分析的方法
2017/11/21 Python
Python使用正则表达式获取网页中所需要的信息
2018/01/29 Python
Python之NumPy(axis=0 与axis=1)区分详解
2019/05/27 Python
Django接收post前端返回的json格式数据代码实现
2019/07/31 Python
python反转列表的三种方式解析
2019/11/08 Python
python实现回旋矩阵方式(旋转矩阵)
2019/12/04 Python
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
美国休闲服装品牌:J.Crew Factory
2017/03/04 全球购物
旧时光糖果:Old Time Candy
2018/02/05 全球购物
是否可以从一个static方法内部发出对非static方法的调用?
2014/08/18 面试题
教师现实表现材料
2014/02/14 职场文书
Mysql数据库事务的脏读幻读及不可重复读详解
2022/05/30 MySQL
Redis唯一ID生成器的实现
2022/07/07 Redis