diff --git a/packages/uni-api/src/index.ts b/packages/uni-api/src/index.ts index 85f8f51dc64c6cdc792c04a80c98980eae73df7a..8a27151068bdc8103cd96d6c96b4e11185d12faa 100644 --- a/packages/uni-api/src/index.ts +++ b/packages/uni-api/src/index.ts @@ -29,6 +29,7 @@ export * from './protocols/media/chooseImage' export * from './protocols/media/chooseVideo' export * from './protocols/media/chooseFile' export * from './protocols/media/getImageInfo' +export * from './protocols/media/getVideoInfo' export * from './protocols/network/request' export * from './protocols/network/downloadFile' diff --git a/packages/uni-api/src/protocols/media/getVideoInfo.ts b/packages/uni-api/src/protocols/media/getVideoInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..005e90cef04d1618abfe6b4ceab64dfdd61f4951 --- /dev/null +++ b/packages/uni-api/src/protocols/media/getVideoInfo.ts @@ -0,0 +1,19 @@ +import { getRealPath } from '@dcloudio/uni-platform' + +export const API_GET_VIDEO_INFO = 'getVideoInfo' +export type API_TYPE_GET_VIDEO_INFO = typeof uni.getVideoInfo + +export const GetVideoInfoOptions: ApiOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src) + }, + }, +} + +export const GetVideoInfoProtocol: ApiProtocol = { + src: { + type: String, + required: true, + }, +} diff --git a/packages/uni-h5/dist/uni-h5.esm.js b/packages/uni-h5/dist/uni-h5.esm.js index 27f9371e6f6c4286f352b0dcd49946b9e86c8d03..f3d886c3a48a37843b335136927965c9b0302199 100644 --- a/packages/uni-h5/dist/uni-h5.esm.js +++ b/packages/uni-h5/dist/uni-h5.esm.js @@ -4635,6 +4635,20 @@ const GetImageInfoProtocol = { required: true } }; +const API_GET_VIDEO_INFO = "getVideoInfo"; +const GetVideoInfoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + } + } +}; +const GetVideoInfoProtocol = { + src: { + type: String, + required: true + } +}; const API_REQUEST = "request"; const dataType = { JSON: "json" @@ -11027,6 +11041,40 @@ const getImageInfo = defineAsyncApi(API_GET_IMAGE_INFO, ({src}, {resolve, reject }; img.src = src; }, GetImageInfoProtocol, GetImageInfoOptions); +const getVideoInfo = defineAsyncApi(API_GET_VIDEO_INFO, ({src}, {resolve, reject}) => { + urlToFile(src, true).then((file) => { + return file; + }).catch(() => { + return null; + }).then((file) => { + const video = document.createElement("video"); + if (video.onloadedmetadata !== void 0) { + const handle = setTimeout(() => { + video.onloadedmetadata = null; + video.onerror = null; + reject(); + }, src.startsWith("data:") || src.startsWith("blob:") ? 300 : 3e3); + video.onloadedmetadata = function() { + clearTimeout(handle); + video.onerror = null; + resolve({ + size: file ? file.size : void 0, + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0 + }); + }; + video.onerror = function() { + clearTimeout(handle); + video.onloadedmetadata = null; + reject(); + }; + video.src = src; + } else { + reject(); + } + }); +}, GetVideoInfoProtocol, GetVideoInfoOptions); const MIMEType = { image: { jpg: "jpeg", @@ -12084,6 +12132,7 @@ var api = /* @__PURE__ */ Object.freeze({ getFileInfo, openDocument, getImageInfo, + getVideoInfo, chooseFile, chooseImage, chooseVideo, @@ -13151,4 +13200,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { ]); } _sfc_main.render = _sfc_render; -export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$n as Audio, index$4 as Button, _sfc_main$m as Canvas, _sfc_main$l as Checkbox, _sfc_main$k as CheckboxGroup, _sfc_main$j as Editor, index$5 as Form, index$3 as Icon, _sfc_main$h as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, _sfc_main$i as ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, index$6 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, usePageRoute, useSubscribe}; +export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$n as Audio, index$4 as Button, _sfc_main$m as Canvas, _sfc_main$l as Checkbox, _sfc_main$k as CheckboxGroup, _sfc_main$j as Editor, index$5 as Form, index$3 as Icon, _sfc_main$h as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, _sfc_main$i as ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, index$6 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, usePageRoute, useSubscribe}; diff --git a/packages/uni-h5/src/service/api/index.ts b/packages/uni-h5/src/service/api/index.ts index 8289426dd0372aea6f7f2b4f6e05fa3e5a0c9da2..9c7ff3e9b637fcf001f5002380a03d3391269cb6 100644 --- a/packages/uni-h5/src/service/api/index.ts +++ b/packages/uni-h5/src/service/api/index.ts @@ -13,6 +13,7 @@ export * from './file/getFileInfo' export * from './file/openDocument' export * from './media/getImageInfo' +export * from './media/getVideoInfo' export * from './media/chooseFile' export * from './media/chooseImage' export * from './media/chooseVideo' diff --git a/packages/uni-h5/src/service/api/media/getVideoInfo.ts b/packages/uni-h5/src/service/api/media/getVideoInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..779d160de7e2d2a266429c70fd419e7779f1c2df --- /dev/null +++ b/packages/uni-h5/src/service/api/media/getVideoInfo.ts @@ -0,0 +1,57 @@ +import { + defineAsyncApi, + API_GET_VIDEO_INFO, + API_TYPE_GET_VIDEO_INFO, + GetVideoInfoOptions, + GetVideoInfoProtocol, +} from '@dcloudio/uni-api' + +import { urlToFile } from '../../../helpers/file' + +export const getVideoInfo = defineAsyncApi( + API_GET_VIDEO_INFO, + ({ src }, { resolve, reject }) => { + urlToFile(src, true) + .then((file) => { + return file + }) + .catch(() => { + return null + }) + .then((file) => { + const video = document.createElement('video') + if (video.onloadedmetadata !== undefined) { + // 部分浏览器(如微信内置浏览器)未播放无法触发loadedmetadata事件 + const handle = setTimeout( + () => { + video.onloadedmetadata = null + video.onerror = null + reject() + }, + src.startsWith('data:') || src.startsWith('blob:') ? 300 : 3000 + ) + // 尝试获取视频的宽高信息 + video.onloadedmetadata = function () { + clearTimeout(handle) + video.onerror = null + resolve({ + size: file ? file.size : undefined, + duration: video.duration || 0, + width: video.videoWidth || 0, + height: video.videoHeight || 0, + }) + } + video.onerror = function () { + clearTimeout(handle) + video.onloadedmetadata = null + reject() + } + video.src = src + } else { + reject() + } + }) + }, + GetVideoInfoProtocol, + GetVideoInfoOptions +)