Vue播放M3U8视频流:Video.js与hls.js两种实现代
M3U8是HLS(HTTP Live Streaming)协议中常用的索引文件格式,在Vue项目中播放M3U8视频流时,通常需要借助video.js配合videojs-contrib-hls插件,或使用更轻量的hls.js库。下面给出两种在Vue组件中可落地的实现方式,包含依赖安装、组件代码、生命周期处理以及兼容性注意事项。一、基于Video.js与videojs-contrib-hls的播放方案
1. 安装依赖
在Vue项目目录下执行:
npm install video.js videojs-contrib-hls
videojs-contrib-hls负责解析M3U8流并将其转换为浏览器可播放的分段数据,video.js则提供UI控件与播放器管理能力。
2. 在Vue组件中引入并初始化播放器
在组件的script中引入video.js、样式文件和HLS插件:
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
import 'videojs-contrib-hls'
export default {
mounted() {
this.initVideoPlayer()
},
methods: {
initVideoPlayer() {
this.player = videojs(this.$refs.videoPlayer, {
autoplay: true,
controls: true,
sources: [{
src: 'your-m3u8-url.m3u8',
type: 'application/x-mpegURL'
}]
})
}
},
beforeDestroy() {
if (this.player) {
this.player.dispose()
}
}
}
注意:sources中的type必须设置为application/x-mpegURL,videojs-contrib-hls才能正确识别该源并启动HLS解析流程。
3. 模板部分:定义video容器
video标签中需要设置ref供Video.js挂载,并且class包含video-js和vjs-default-skin。若不在初始化时传入sources,也可借助data-setup属性启用自动初始化,但通常更推荐通过ref手动初始化,便于控制播放器实例。
<template>
<div>
<video
ref="videoPlayer"
class="video-js vjs-default-skin"
width="640"
height="360"
data-setup="{}">
</video>
</div>
</template>
4. 样式适配
通过CSS限制播放器宽度,使其在不同屏幕下都能正常展示:
.video-js {
width: 100%;
max-width: 640px;
margin: 0 auto;
}
5. 完整组件示例(支持传入src)
将播放地址通过props传入组件,便于复用。
<template>
<div class="video-container">
<video ref="videoPlayer" class="video-js"></video>
</div>
</template>
<script>
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
import 'videojs-contrib-hls'
export default {
props: {
src: {
type: String,
required: true
}
},
mounted() {
this.initPlayer()
},
methods: {
initPlayer() {
this.player = videojs(this.$refs.videoPlayer, {
autoplay: false,
controls: true,
sources: [{
src: this.src,
type: 'application/x-mpegURL'
}]
})
}
},
beforeDestroy() {
if (this.player) {
this.player.dispose()
}
}
}
</script>
<style scoped>
.video-container {
margin: 20px auto;
width: 80%;
}
</style>
二、基于hls.js的轻量级播放方案
如果项目不想引入体积较大的video.js,可以直接使用hls.js。hls.js是专门处理HLS流的前端库,在支持Media Source Extensions(MSE)的浏览器中表现良好。
1. 安装hls.js
npm install hls.js
2. 组件内实现
<template>
<video ref="videoPlayer" controls></video>
</template>
<script>
import Hls from 'hls.js'
export default {
data() {
return {
hls: null
}
},
mounted() {
this.loadVideo()
},
methods: {
loadVideo() {
const videoSrc = 'your-m3u8-url.m3u8'
const video = this.$refs.videoPlayer
// 优先使用hls.js:通过MSE驱动播放
if (Hls.isSupported()) {
this.hls = new Hls()
this.hls.loadSource(videoSrc)
this.hls.attachMedia(video)
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// Safari等原生支持HLS的浏览器直接设置src
video.src = videoSrc
}
}
},
beforeDestroy() {
// 销毁hls实例,释放资源
if (this.hls) {
this.hls.destroy()
}
}
}
</script>
三、关键注意事项
- 跨域问题:M3U8地址必须允许跨域访问,否则播放器无法拉取ts分片。若接口和视频流不在同一域名下,需要在服务端配置CORS策略,允许当前页面域名发起请求。
- 移动端内联播放:在iOS/Android的WebView或部分移动浏览器中,如果想在页面内直接播放而不跳转全屏,需要给video标签增加playsinline属性。
- HTTPS环境:如果当前页面是通过HTTPS访问,M3U8地址也必须是HTTPS。混合内容(HTTPS页面加载HTTP流)会被浏览器拦截,导致视频无法播放。
- 动态切换视频源:如果是直播或监控场景,播放地址可能变化,建议在设置新源前先调用player.src(newSource)或重新创建hls实例,同时注意销毁旧的hls对象。
- videojs-contrib-hls插件已经停止积极维护,较新版本的video.js建议直接集成hls.js或使用http-streaming组件。如果遇到兼容性问题,请先检查video.js版本和插件版本是否匹配。
以上两种方式分别适用于不同场景:Video.js方案组件完善、自带控制条和样式,适合快速实现标准播放器;hls.js方案更轻量,适合已有自定义播放器UI或需要直接操作HLS流的业务。开发者可根据实际需求选择。
Re: Vue播放M3U8视频流:Video.js与hls.js两种实现代
作为在 Vue 里折腾过 M3U8 播放的人,看到这么详细的两种实现方案真的很受益。之前我项目里用的是 hls.js 那条路,确实轻量,但当时没注意到你说的 MSE 兼容性问题,在部分旧浏览器上踩了坑。Video.js 那条路我还没试过,看你写的组件封装思路挺清晰,尤其是关于 `type` 必须设置为 `application/x-mpegURL` 以及手动初始化播放器的提醒,很实用,下次遇到需求可以照着试试。感谢整理分享!Re: Vue播放M3U8视频流:Video.js与hls.js两种实现代
感谢分享,写得很清楚,正好最近在折腾 Vue 里播 M3U8,参考你的方案省了不少事。 想补充一点小经验:videojs-contrib-hls 这个插件在 video.js 7 之后维护不太积极,如果遇到兼容性或打包警告,可以考虑直接用 @videojs/http-streaming(VHS),它是 video.js 官方内置的流媒体引擎,用法上基本不用改太多。另一个就是 hls.js 的方案确实轻量,但要注意 iOS 上原生对 HLS 的支持,Safari 里可能不需要走 MSE,最好做个判断让原生 video 直接播,避免兼容问题。 另外生命周期里调用 dispose 这步很关键,不然组件频繁切换容易内存泄漏,这点楼主考虑得很到位。Re: Vue播放M3U8视频流:Video.js与hls.js两种实现代
看到这篇分享很实用,正好最近也在搞 Vue 里的 HLS 播放。两种方案的对比很清楚,尤其 hls.js 那版确实轻量很多。补充一点小经验:videojs-contrib-hls 官方好像已经不再积极维护了,新项目的话直接上 hls.js 或者 video.js 7 + hls.js 插件会更稳。另外如果视频地址会动态变化,记得在切换 src 时先 dispose 掉旧播放器实例,再重新初始化,避免内存泄漏和状态残留。感谢楼主整理~
页:
[1]