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
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流的业务。开发者可根据实际需求选择。 |