NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.56k stars 4.8k forks source link

chooseVideo 没有在 Safari 中正确触发回调 #14678

Open axetroy opened 1 year ago

axetroy commented 1 year ago

相关平台

H5

浏览器版本: Safari 使用框架: React

复现步骤

        const res = await Taro.chooseVideo({
            fail: (err) => {
                console.log('fail', err)
            },
            success: function (r) {
                console.log('success', r)
            },
            complete: (r) => {
                console.log('complate', r)
            },
        })

无论是回调的写法,还是 Promise 的写法,都没有回调。

Android 正常

期望结果

.

实际结果

触发了文件选择,选择之后,既没有触发 success,也没有触发 fail

环境信息

👽 Taro v3.6.17

  Taro CLI 3.6.17 environment info:
    System:
      OS: Windows 10 10.0.19045
    Binaries:
      Node: 16.20.2 - C:\Program Files\nodejs\node.EXE 
      Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD   
      npm: 6.14.18 - C:\Program Files\nodejs\npm.CMD   
    npmPackages:
      @tarojs/cli: 3.6.17 => 3.6.17
      @tarojs/components: 3.6.17 => 3.6.17
      @tarojs/helper: 3.6.17 => 3.6.17
      @tarojs/plugin-framework-react: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-alipay: 3.6.17 => 3.6.17 
      @tarojs/plugin-platform-h5: 3.6.17 => 3.6.17     
      @tarojs/plugin-platform-jd: 3.6.17 => 3.6.17     
      @tarojs/plugin-platform-qq: 3.6.17 => 3.6.17     
      @tarojs/plugin-platform-swan: 3.6.17 => 3.6.17   
      @tarojs/plugin-platform-tt: 3.6.17 => 3.6.17     
      @tarojs/plugin-platform-weapp: 3.6.17 => 3.6.17  
      @tarojs/react: 3.6.17 => 3.6.17
      @tarojs/runtime: 3.6.17 => 3.6.17
      @tarojs/shared: 3.6.17 => 3.6.17
      @tarojs/taro: 3.6.17 => 3.6.17
      @tarojs/taro-h5: 3.6.17 => 3.6.17
      @tarojs/taro-loader: 3.6.17 => 3.6.17
      @tarojs/webpack5-runner: 3.6.17 => 3.6.17
      babel-plugin-transform-taroapi: 3.6.17 => 3.6.17
      babel-preset-taro: 3.6.17 => 3.6.17
      eslint-config-taro: 3.6.17 => 3.6.17
      react: ^18.2.0 => 18.2.0
      taro-ui: ^3.1.0 => 3.1.0
axetroy commented 1 year ago

https://github.com/NervJS/taro/blob/180c9e47d8b5243c3a9135d807c440029b101a73/packages/taro-h5/src/api/media/video/chooseMedia.ts#L146-L164

问题已经找到,因为 safari 下,永远不会触发 oncanplay,所以不会resolve,也不会 reject。

应该是不支持播放 video/quicktime 视频

axetroy commented 1 year ago

已经解决,在 Reader 的 onload 事件 resolve 之后即可

   // 对齐旧版本实现 
   reader.onload = (event) => { 
     res.tempFilePath = event.target?.result as string 
+   resolve(res)
   } 

另外为了 thumbTempFilePath 然后加载整个视频,并且还有兼容性,觉得不太值当

diff --git a/node_modules/@tarojs/taro-h5/dist/api/media/video/chooseMedia.js b/node_modules/@tarojs/taro-h5/dist/api/media/video/chooseMedia.js
index 7227c70..dbfe8f4 100644
--- a/node_modules/@tarojs/taro-h5/dist/api/media/video/chooseMedia.js
+++ b/node_modules/@tarojs/taro-h5/dist/api/media/video/chooseMedia.js
@@ -134,24 +134,53 @@ const chooseMedia = function (options, methodName = 'chooseMedia') {
                 video.crossOrigin = 'Anonymous';
                 video.preload = 'metadata';
                 video.src = res.tempFilePath;
+
+                const canPlay = video.canPlayType(file.type);
+
+
+                if (canPlay === 'probably') {
+                  console.log('浏览器可能支持播放该视频类型。');
+                } else if (canPlay === 'maybe') {
+                  console.log('浏览器可能支持播放该视频类型,但不确定性较大。');
+                } else {
+                  console.log('浏览器不支持播放该视频类型。');
+                }
+
                 return new Promise((resolve, reject) => {
-                    // 对齐旧版本实现
-                    reader.onload = (event) => {
-                        var _a;
-                        res.tempFilePath = (_a = event.target) === null || _a === void 0 ? void 0 : _a.result;
-                    };
+                    switch (canPlay) {
+                      case 'probably':
+                        // 对齐旧版本实现
+                        reader.onload = (event) => {
+                            var _a;
+                            res.tempFilePath = (_a = event.target) === null || _a === void 0 ? void 0 : _a.result;
+                            resolve(res)
+                        };
+                        video.onloadedmetadata = () => {
+                            res.duration = video.duration;
+                            res.height = video.videoHeight;
+                            res.width = video.videoWidth;
+                        };
+                        video.oncanplay = () => {
+                            res.thumbTempFilePath = getThumbTempFilePath(video, res.height, res.width, 0.8);
+                            resolve(res);
+                        };
+                        video.onerror = e => reject(e);
+                        break
+                      case 'maybe':
+                      default:
+                        // 对齐旧版本实现
+                        reader.onload = (event) => {
+                            var _a;
+                            res.tempFilePath = (_a = event.target) === null || _a === void 0 ? void 0 : _a.result;
+
+                            resolve(res)
+                        };
+                        break
+                    }
+
                     reader.onerror = e => reject(e);
                     reader.readAsDataURL(res.originalFileObj);
-                    video.onloadedmetadata = () => {
-                        res.duration = video.duration;
-                        res.height = video.videoHeight;
-                        res.width = video.videoWidth;
-                    };
-                    video.oncanplay = () => {
-                        res.thumbTempFilePath = getThumbTempFilePath(video, res.height, res.width, 0.8);
-                        resolve(res);
-                    };
-                    video.onerror = e => reject(e);
+
                 });
             }
             else {
sutras commented 1 year ago

是的,想不到如今才有人发现这个问题,说明用Taro的人还是很少。

最近写了一个组件库:https://github.com/sutras/sard

为了兼容H5,专门针对H5自行实现了chooseVideo接口。

liuyunzyj commented 1 year ago

我在使用Taro.chooseMedia也遇到了这个问题。