ck@123911.net 6 days ago
parent
commit
d22bb68251
1 changed files with 48 additions and 10 deletions
  1. 48 10
      components/DomVideoPlayer/DomVideoPlayer.vue

+ 48 - 10
components/DomVideoPlayer/DomVideoPlayer.vue

@@ -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) {