vue+node 实现视频在线播放的实例代码
Memory_Space-2020 人气:11.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(); } } } },
总结
加载全部内容