微信公众号外包 项目开发中遇到一例要求页面可以播放流媒体,一开始的视频格式是flv mp4和m3u8格式的,但是开发中遇到了问题,
视频格式选择
mp4格式
在pc上可以播放但是放在手机上就无法播放了,于是和后端沟通后改为使用flv格式。
flv格式
使用flvjs实现了在pc和安卓手机上播放,都没有问题以为没问题了?我真是天真,苹果手机不支持flv。
查询后得到的答案是:
由于依赖Media Source Extensions,目前所有i0S和Android4.4.4以下里的浏览器都不支持,也 就是说目前对于移动端flv.js基本是不能用的。
m3u8格式
和后端沟通改用m3u8格式的,这次应该没问题了吧.
通过使用videojs来渲染播放器,首先ios测试没问题,正常播放视频,安卓正常播放没问题,pc谷歌浏览器播放报错了:报了一个_createClass2 is not defined
错误,我是愣没查到是怎么来的,也没找到解决方案。还能不能好好相处了,咋这么多坑呢?
最后实在是没办法了采用了一个折中的办法,弄两个播放器,判断终端如果是ios就使用videojs播放器,其他就使用flv.js播放器。
开发环境
uniapp h5
终端判断组件
<template>
<view class="coverImg">
<!-- 判断是否是苹果 -->
<view class="attachments" v-if="platform == 'ios'">
<videojs :isCover="isCover" v-if="hlsUrl" :src="hlsUrl"></videojs>
</view>
<view class="attachments" v-else>
<flv :isCover="isCover" v-if="flvUrl" :src="flvUrl"></flv>
</view>
</view>
</template>
<script>
import {
playstart
} from '@/config/api.js'
import flv from '@/components/flv.vue'
import videojs from '@/components/videojs.vue'
import configs from '@/config/config.js'
export default {
components: {
flv,
videojs
},
data() {
return {
configs,
platform: ''
}
},
props: {
flvUrl: {
type: String,
default () {
return ''
}
},
isCover: {
type: Boolean,
default () {
return true
}
},
hlsUrl: {
type: String,
default () {
return ''
}
},
},
mounted() {
this.platform = uni.getSystemInfoSync().platform
},
watch: {},
methods: {}
}
</script>
<style scoped lang="scss">
.attachments {
width: 100%;
height: 100%;
position: relative;
}
.coverImg {
width: 100%;
height: 100%;
position: relative;
}
</style>
flvjs实现
/**
* @Author: 858834013@qq.com
* @Name: flvjs组件
* @Date: 2023年02月09日20:15:28
* @Desc: uniapp使用flvjs播放视频
*/
<template>
<div class="videoBody" ref="videoElement" id="videoElement">
</div>
</template>
<script>
import flvjs from 'flv.js'
import imgs from '@/static/message/shipinimg.png'
export default {
name: "flv",
components: {
imgs
},
props: {
src: {
type: String,
default () {
return '';
}
},
isCover: {
type: Boolean,
default () {
return true
}
},
},
data() {
return {
flvPlayer: null,
isPlay: false,
}
},
watch: {
src() {
this.getPlay()
}
},
mounted() {
this.getPlay()
},
methods: {
getPlay() {
var that = this;
console.log(flvjs)
if (flvjs.isSupported()) {
let video = document.createElement('video');
video.id = 'video';
video.style = 'width: 100%; height: 100%;';
video.controls = that.isCover ? false : true;
video.preload = "auto"
// video.poster = imgs
video.autoplay = that.isCover ? false : true
video.muted = that.isCover ? false : true
video.setAttribute('playsinline', that.isCover ? false : true) //IOS微信浏览器支持小窗内播放
video.setAttribute("crossOrigin", "anonymous");
video.setAttribute('webkit-playsinline', true)
//这个bai属性是ios 10中设置可以让视频在小du窗内播放,也就是不是全zhi屏播放的video标签的一个属性
video.setAttribute('x5-video-player-type', 'h5') //安卓 声明启用同层H5播放器 可以在video上面加东西
let source = document.createElement('source');
source.src = that.src;
// return
that.$refs.videoElement.appendChild(video);
that.flvPlayer = flvjs.createPlayer({
type: 'flv',
url: that.src
})
that.flvPlayer.attachMediaElement(video)
that.flvPlayer.load()
if (!that.isCover) {
setTimeout(() => {
that.flvPlayer.play()
}, 1000)
}
}
},
play() {
this.isPlay = true
this.flvPlayer.play()
},
pause() {
this.isPlay = false
this.flvPlayer.pause()
},
}
}
</script>
<style lang="scss" scoped>
.videoBody {
position: relative;
z-index: 100;
width: 100%;
height: 100%;
}
</style>
videojs实现
/**
* @Author: 858834013@qq.com
* @Name: videojs组件
* @Date: 2023年02月09日20:15:28
* @Desc: uniapp使用videojs播放视频
*/
<template>
<div class="video-js" ref="videos" style="width: 100%;height: 100%;">
</div>
</template>
<script>
import configs from '@/config/config.js'
export default {
data() {
return {
configs
}
},
props: {
src: {
type: String,
default () {
return '';
}
},
isCover: {
type: Boolean,
default () {
return true
}
},
},
watch: {
src() {
this.getPlay()
}
},
mounted() {
var that = this;
that.getPlay()
uni.$on('onShow', function(data) {
that.getPlay()
});
},
methods: {
getPlay() {
var that = this;
let video = document.createElement('video');
video.id = 'video';
video.style = 'width: 100%; height: 100%;';
video.controls = that.isCover ? false : true;
video.preload = "auto"
// video.poster = imgs
video.autoplay = that.isCover ? false : true
video.muted = that.isCover ? false : true
video.setAttribute('playsinline', that.isCover ? false : true) //IOS微信浏览器支持小窗内播放
video.setAttribute("crossOrigin", "anonymous");
video.setAttribute('webkit-playsinline', true)
let source = document.createElement('source');
source.src = this.src;
video.appendChild(source);
// return
this.$refs.videos.appendChild(video);
let player = this.$video('video', {
poster: '', // 视频封面图地址
playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
autoDisable: true,
preload: that.isCover ? 'meta' :
'auto', //auto - 当页面加载后载入整个视频 meta - 当页面加载后只载入元数据 none - 当页面加载后不载入视频
language: 'zh-CN',
fluid: true, // 自适应宽高
muted: that.isCover ? false : true, // 是否静音
aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
controls: that.isCover ? false :
true, //是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
autoplay: true, //如果true,浏览器准备好时开始回放。 autoplay: "muted", // //自动播放属性,muted:静音播放
loop: true, // 导致视频一结束就重新开始。 视频播放结束后,是否循环播放
controlBar: {
volumePanel: { //声音样式
inline: false // 不使用水平方式
},
timeDivider: true, // 时间分割线
// durationDisplay: true, // 总时间
// progressControl: true, // 进度条
remainingTimeDisplay: true, //当前以播放时间
fullscreenToggle: true, //全屏按钮
pictureInPictureToggle: true, //画中画
}
}, function() {
this.on('error', function(err) { //请求数据时遇到错误
console.log("请求数据时遇到错误", err)
});
this.on('stalled', function(stalled) { //网速失速
console.log("网速失速", stalled)
});
this.on('play', function() { //开始播放
console.log("开始播放")
player.pause()
// var rotateBtn = player.controlBar.addChild('button')
// rotateBtn.addClass('icon_jianji')
// rotateBtn.on('click', function() {})
});
this.on('pause', function() { //暂停
console.log("暂停")
});
// this.on('timeupdate', function(timeupdate) {
// // console.log(timeupdate)
// })
});
},
}
}
</script>
<style scoped lang="scss">
.video-js {
position: relative;
width: 100%;
height: 100%;
video {
position: relative;
width: 100%;
height: 100%;
}
}
</style>