|
@@ -130,6 +130,11 @@ export default {
|
|
|
pause() {
|
|
|
this.eventCommand = 'pause'
|
|
|
},
|
|
|
+ // 用户交互触发播放(特别适用于iOS)
|
|
|
+ playWithUserGesture() {
|
|
|
+ // 确保在用户交互的上下文中调用
|
|
|
+ this.eventCommand = 'play'
|
|
|
+ },
|
|
|
// 重置自定义函数指令
|
|
|
resetFunc() {
|
|
|
this.renderFunc = {
|
|
@@ -209,16 +214,24 @@ export default {
|
|
|
|
|
|
const { autoplay, muted, controls, loop, playbackRate, objectFit, poster } = this.renderProps
|
|
|
videoEl.src = src
|
|
|
- videoEl.autoplay = autoplay
|
|
|
+ videoEl.autoplay = autoplay && muted // iOS只允许静音状态下自动播放
|
|
|
videoEl.controls = controls
|
|
|
videoEl.loop = loop
|
|
|
videoEl.muted = muted
|
|
|
videoEl.playbackRate = playbackRate
|
|
|
videoEl.id = this.playerId
|
|
|
- // videoEl.setAttribute('x5-video-player-type', 'h5')
|
|
|
- videoEl.setAttribute('preload', 'auto')
|
|
|
- videoEl.setAttribute('playsinline', true)
|
|
|
- videoEl.setAttribute('webkit-playsinline', true)
|
|
|
+
|
|
|
+ // iOS兼容性属性设置
|
|
|
+ if (this.isApple()) {
|
|
|
+ videoEl.setAttribute('playsinline', true)
|
|
|
+ videoEl.setAttribute('webkit-playsinline', true)
|
|
|
+ videoEl.setAttribute('x5-playsinline', true)
|
|
|
+ // iOS需要预加载元数据
|
|
|
+ videoEl.setAttribute('preload', 'metadata')
|
|
|
+ } else {
|
|
|
+ videoEl.setAttribute('preload', 'auto')
|
|
|
+ }
|
|
|
+
|
|
|
videoEl.setAttribute('crossorigin', 'anonymous')
|
|
|
videoEl.setAttribute('controlslist', 'nodownload')
|
|
|
videoEl.setAttribute('disablePictureInPicture', true)
|
|
@@ -228,7 +241,6 @@ export default {
|
|
|
videoEl.style.height = '100%'
|
|
|
|
|
|
// 插入视频元素
|
|
|
- // document.getElementById(this.wrapperId).appendChild(videoEl)
|
|
|
const playerWrapper = document.getElementById(this.wrapperId)
|
|
|
playerWrapper.insertBefore(videoEl, playerWrapper.firstChild)
|
|
|
|
|
@@ -432,9 +444,19 @@ export default {
|
|
|
loadFirstFrame() {
|
|
|
let { autoplay, muted } = this.renderProps
|
|
|
if (this.isApple()) {
|
|
|
- this.videoEl.play()
|
|
|
- if (!autoplay) {
|
|
|
- this.videoEl.pause()
|
|
|
+ // iOS严格限制:只有在用户交互或静音状态下才能自动播放
|
|
|
+ if (autoplay && muted) {
|
|
|
+ // 添加错误处理
|
|
|
+ const playPromise = this.videoEl.play()
|
|
|
+ if (playPromise !== undefined) {
|
|
|
+ playPromise.catch(error => {
|
|
|
+ console.warn('iOS autoplay failed:', error)
|
|
|
+ // 如果自动播放失败,不做任何操作,等待用户交互
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (!autoplay) {
|
|
|
+ // 如果不是自动播放,尝试加载第一帧但不播放
|
|
|
+ this.videoEl.load()
|
|
|
}
|
|
|
} else {
|
|
|
// optimize: timeout 延迟调用是为了规避控制台的`https://goo.gl/LdLk22`这个报错
|
|
@@ -458,7 +480,23 @@ export default {
|
|
|
triggerCommand(eventType) {
|
|
|
if (eventType) {
|
|
|
this.$ownerInstance.callMethod('resetEventCommand')
|
|
|
- this.videoEl && this.videoEl[eventType]()
|
|
|
+ if (this.videoEl) {
|
|
|
+ // 为iOS添加Promise错误处理
|
|
|
+ if (eventType === 'play') {
|
|
|
+ const playPromise = this.videoEl.play()
|
|
|
+ if (playPromise !== undefined) {
|
|
|
+ playPromise.catch(error => {
|
|
|
+ console.warn('Video play failed:', error)
|
|
|
+ this.$ownerInstance.callMethod('eventEmit', {
|
|
|
+ event: 'error',
|
|
|
+ data: { type: 'play_failed', message: error.message }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.videoEl[eventType]()
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
triggerFunc(func) {
|