说明,此路不通
发布时间:2025-06-24 18:34:56 作者:北方职教升学中心 阅读量:731
一开始:
其实用的是xgplayer(西瓜视频)。说明,此路不通。
官网地址:Jessibuca
如何使用:
前端如何使用?建议直接下载相关资源,静态引入。
2.前端需要接收视频流,并寻找合适的播放插件。
vue中使用详情:
首先,上边的三个文件引入public。
但是无法播放,现象就是一直loading;
后来,查了好多资料,发现一个issue:
流数据正常下载,xgplayer-flv无法播放 · Issue #604 · bytedance/xgplayer · GitHub。
<!-- public下的index.html 直接引入js文件-->....<script src="<%= BASE_URL %>jessibuca.js"></script>.....
然后,创建视频播放组件 LiveVideoPlay.vue:
<script>export default { name: "LiveVideoPlay", props: { // 播放地址 playUrl: { type: String, required: true, }, // 目标domid id: { type: String, required: true, }, }, data() { return { player: null, }; }, methods: { // 初始化视频组件 initPlayer() { if (Jessibuca) { this.player = new Jessibuca({ container: document.getElementById(this.id), //jessibuca需要容器 videoBuffer: 0.2, // 缓存时长 isResize: false, loadingText: "疯狂加载中...", useMSE: true, useWCS: true, debug: true, background: "@/assets/icons/svg/no-video.svg", supportDblclickFullscreen: true, showBandwidth: true, // 显示网速 operateBtns: { fullscreen: true, screenshot: true, play: true, audio: true, }, forceNoOffscreen: true, isNotMute: false, timeout: 10, }); //console.log("this.player ----- ", this.player, this.playUrl); this.player.play(this.playUrl); } }, }, beforeDestroy() { // 销毁视频 if (this.player) { this.player.destroy(); this.player = null; } }, mounted() { this.initPlayer(); },};</script><template> <div class="video-player-outer" :id="id"></div></template><style>.video-player-outer { width: 100%; height: 100%;}</style>
最后,父组件中直接引用:
// 父组件中直接使用该组件<script>import LiveVideoPlay from "./LiveVideoPlay.vue";export default { name: '', components: { LiveVideoPlay }, data () { return { playUrl1: null, playUrl2: null, showV1: false, showV2: false, } }, methods: { handlePlayVideo(v) { if (v == 1) { this.playUrl1 = "https://xxxxxx/live/02.live.flv"; this.showV1 = true; } else if (v == 2) { this.playUrl2 = "https://xxxxxx/live/02.live.flv"; this.showV2 = true; } }, StopPlayVideo(v) { if (v == 1) { this.showV1 = false; } else if (v == 2) { this.showV2 = false; } }, },}</script><template> <div class="box"> <div class="video-box-item"> <el-button @click="handlePlayVideo(1)">播放视频1</el-button> <el-button @click="StopPlayVideo(1)">停止视频1</el-button> <LiveVideoPlay v-if="showV1" :playUrl="playUrl1" id="v1" /> </div> <div class="video-box-item"> <el-button @click="handlePlayVideo(2)">播放视频2</el-button> <el-button @click="StopPlayVideo(2)">停止视频2</el-button> <LiveVideoPlay v-if="showV2" :playUrl="playUrl2" id="v2" /> </div> </div></template>
如上,可以试一试自己的播放地址是否可以成功播放视频.如果你的需求不那么高,不考虑延迟,到这里基本就够了,不需要卷下去.
但是,如果你的要求比较高,又不想买jecibuca的收费版本,那么请继续往下看, 有更好的解决方案.
优中选优:
现在这个功能是做出来了,但是视频延迟的问题比较突出.比如,我控制摄像头旋转一下位置,在上述解决方案中,会明显发现摄像头触发旋转进而回传视频明显延迟.那怎么办? 如果你要求不高,那么上边的解决方案足够使用,但是如果要求低延迟,那么就不得不祭出另个大杀器了 - LiveQing.
官网地址: LivePlayer H5播放器 | 青柿视频流媒体服务解决方案
如何使用? vue2中大概分为这几步骤(vue3+vite的可以参考官网):
1. 安装 Liveplayer:
npm install @liveqing/liveplayer
2. 安装 webpack 插件 copy-webpack-plugin
npm install copy-webpack-plugin@4.6.0
注意: 如果你的版本是vuecli4.0+, 那么以上这个版本就够用了.但是 如果你的vuecli5.0+, 你需要升级这个copywebpack-plugins的版本,比如 copy-webpack-plugin@11.0.0.亲测有效,一定要注意!!!
3. 配置vue.config.js
/** vue.config.js */// ***** 注意 还是vuecli版本的问题// ***** 如果你的vuelci4.0+ 就用下边这个配置const CopyWebpackPlugin = require("copy-webpack-plugin");module.exports = { ... configureWebpack: (config) => { config.devtool = "source-map"; config.output.libraryExport = "default"; /* 解决import UMD打包文件时, 组件install方法执行报错的问题!! */ // 增加配置如下 主要是 plugins const plugins = [ new CopyWebpackPlugin([ { from: "node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml", }, { from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf", }, { from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js", to: "livePlayer/", }, ]), ]; config.plugins.push(...plugins); } }, ...}// ***** 如果你的vuelci5.0+ 就用下边这个配置const CopyWebpackPlugin = require("copy-webpack-plugin");module.exports = { ..... chainWebpack(config) { // 增加插件 config.plugin('copy').use(CopyWebpackPlugin, [ { patterns: [ { from: "node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml", }, { from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf", }, { from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js", to: "livePlayer/", }, ] } ]) } }
4. public中的index.html中引入js文件
5. 封装播放视频组件
<template> <LivePlayer class="component-wrapper video-panel" :class="{ fullscreen: flag }" :videoUrl="options.url" :videoTitle="options.title" :poster="options.poster" :controls="options.controls" :autoplay="options.autoplay" :live="options.live" :hide-snapshot-button="options.hideSnapshot" :muted="options.muted" :fluent="options.fluent" :stretch="options.stretch" :aspect="options.aspect" :loading="options.loading" :hide-big-play-button="options.hideBigPlay" @fullscreen="onFullscreen" > <slot></slot> </LivePlayer></template><script>import LivePlayer from "@liveqing/liveplayer";export default { name: "LiveVideoRtcPlayer", components: { LivePlayer, }, props: { params: { type: String, }, }, data() { return { flag: false, }; }, computed: { options() { return { // 播放地址 url: this.params, // 视频标题 title: "", // 视频封面图片 poster: "", // 播放器控制栏 controls: true, // 隐藏截图 hideSnapshot: true, // 是否直播 live: true, // 是否自动播放 autoplay: true, // 是否静音 muted: true, // 流畅模式 fluent: true, // 是否拉伸 stretch: true, // 全屏 - 适应div aspect: "fullscreen", // 指示加载状态 loading: true, // 隐藏起播状态下的大播放按钮 hideBigPlay: true, }; }, }, created() { console.log("配置 ----- ", this.options); }, beforeDestroy() { if (this.options) { this.options.url = ""; } this.onExitFullscreen(); }, methods: { onExitFullscreen() { this.flag = false; }, onFullscreen(status) { this.flag = status; if (!status) { this.onExitFullscreen(); return; } }, },};</script><style lang="scss" scoped>.component-wrapper.video-panel { position: relative; width: 100%; height: 100%; .video-wrapper .video-js { background-color: rgba(32, 46, 71, 0.6); .video-title { top: 4px; right: unset; left: 4px; padding: 4px 6px; max-width: 80%; font-size: 16px; } .video-control { position: absolute; top: 100%; left: 50%; transform: translate(-50%, -140%); margin-top: 0; } } &.fullscreen .video-wrapper .video-js { .video-title { top: 60px; right: unset; left: 20px; padding: 5px 8px 6px; background: rgba(4, 16, 37, 0.6); border-radius: 4px; } }}</style>
6. 父组件中引用播放组件
<template> <div id="app"> <!-- 视频 --> <div class="video-box"> <el-button @click="handlePlayVideo(1)">播放视频1</el-button> <el-button @click="StopPlayVideo(1)">停止视频1</el-button> <div class="video-box-item"> <LiveVideoRtcPlayer v-if="showV1" :params="playUrl1" id="v1" /> </div> <el-button @click="handlePlayVideo(2)">播放视频2</el-button> <el-button @click="StopPlayVideo(2)">停止视频2</el-button> <div class="video-box-item"> <LiveVideoRtcPlayer v-if="showV2" :params="playUrl2" id="v2" /> </div> </div> </div></template><script>//import Child from "./Child.vue";//import LiveVideoPlay from "./LiveVideoPlay.vue";import LiveVideoRtcPlayer from "./LiveVideoRtcPlayer.vue";export default { name: "App", components: { //LiveVideoPlay, LiveVideoRtcPlayer, }, data() { return { playUrl1: null, playUrl2: null, showV1: false, showV2: false, }; }, methods: { handlePlayVideo(v) { if (v == 1) { // this.playUrl1 = // "https://xxxxxxxxxxxx/live/02.live.flv"; this.playUrl1 = "webrtcs://xxxxxxxxxxxxx/live/index/api"; this.showV1 = true; } else if (v == 2) { this.playUrl2 = 'xxxxx 播放地址'; this.showV2 = true; } }, StopPlayVideo(v) { if (v == 1) { this.showV1 = false; } else if (v == 2) { this.showV2 = false; } }, },};</script><style lang="scss" scoped>#app { height: 100%;}#app ::v-deep .box { font-size: 30px;}.video-box { width: 100%; height: 600px; overflow: hidden; &-item { width: 300px; height: 400px; float: left; overflow: hidden; background-color: #f1f2f3; margin-left: 50px; position: relative; }}</style><style lang="scss"></style>
测试一下,nice.
累了,就这样吧.