@draftbit/core 54.0.4-6c949a.2 → 54.0.4-8202b6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js +1 -1
- package/lib/commonjs/components/MediaPlayer/MediaPlaybackWrapper.js +1 -1
- package/lib/commonjs/components/MediaPlayer/MediaPlayerCommon.js +1 -1
- package/lib/commonjs/components/MediaPlayer/VideoPlayer/VideoPlayer.js +1 -1
- package/lib/typescript/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.d.ts +3 -1
- package/lib/typescript/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js +69 -54
- package/lib/typescript/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/MediaPlaybackWrapper.d.ts +3 -2
- package/lib/typescript/src/components/MediaPlayer/MediaPlaybackWrapper.js +19 -21
- package/lib/typescript/src/components/MediaPlayer/MediaPlaybackWrapper.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.d.ts +5 -4
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.js +3 -26
- package/lib/typescript/src/components/MediaPlayer/MediaPlayerCommon.js.map +1 -1
- package/lib/typescript/src/components/MediaPlayer/VideoPlayer/VideoPlayer.d.ts +14 -4
- package/lib/typescript/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js +125 -62
- package/lib/typescript/src/components/MediaPlayer/VideoPlayer/VideoPlayer.js.map +1 -1
- package/lib/typescript/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx +84 -72
- package/src/components/MediaPlayer/MediaPlaybackWrapper.tsx +21 -24
- package/src/components/MediaPlayer/MediaPlayerCommon.ts +8 -34
- package/src/components/MediaPlayer/VideoPlayer/VideoPlayer.tsx +213 -86
|
@@ -1 +1 @@
|
|
|
1
|
-
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var React=_interopRequireWildcard(require("react"));var
|
|
1
|
+
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;exports.mapToMediaPlayerStatus=mapToMediaPlayerStatus;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var React=_interopRequireWildcard(require("react"));var _expoAudio=require("expo-audio");var _MediaPlayerCommon=require("../MediaPlayerCommon");var _MediaPlaybackWrapper=_interopRequireDefault(require("../MediaPlaybackWrapper"));var _jsxRuntime=require("react/jsx-runtime");var _this=this,_jsxFileName="/home/runner/work/react-native-jigsaw/react-native-jigsaw/packages/core/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx";function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap(),t=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(e){return e?t:r;})(e);}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=_getRequireWildcardCache(r);if(t&&t.has(e))return t.get(e);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var u in e)if("default"!==u&&{}.hasOwnProperty.call(e,u)){var i=a?Object.getOwnPropertyDescriptor(e,u):null;i&&(i.get||i.set)?Object.defineProperty(n,u,i):n[u]=e[u];}return n.default=e,t&&t.set(e,n),n;}var HeadlessAudioPlayer=React.forwardRef(function(_ref,ref){var source=_ref.source,_ref$interruptionMode=_ref.interruptionMode,interruptionMode=_ref$interruptionMode===void 0?"lower volume":_ref$interruptionMode,_ref$playsInBackgroun=_ref.playsInBackground,playsInBackground=_ref$playsInBackgroun===void 0?false:_ref$playsInBackgroun,_ref$playsInSilentMod=_ref.playsInSilentModeIOS,playsInSilentModeIOS=_ref$playsInSilentMod===void 0?false:_ref$playsInSilentMod,_ref$playThroughEarpi=_ref.playThroughEarpieceAndroid,playThroughEarpieceAndroid=_ref$playThroughEarpi===void 0?false:_ref$playThroughEarpi,onPlaybackStatusUpdateProp=_ref.onPlaybackStatusUpdate,onPlaybackFinish=_ref.onPlaybackFinish,_ref$isLooping=_ref.isLooping,isLooping=_ref$isLooping===void 0?false:_ref$isLooping,_ref$volume=_ref.volume,volume=_ref$volume===void 0?1.0:_ref$volume;var stableSource=(0,_MediaPlayerCommon.useSourceDeepCompareMemoize)((0,_MediaPlayerCommon.normalizeBase64Source)(source,"audio"));var player=(0,_expoAudio.useAudioPlayer)(stableSource);var _React$useState=React.useState(false),_React$useState2=(0,_slicedToArray2.default)(_React$useState,2),isPlaying=_React$useState2[0],setIsPlaying=_React$useState2[1];React.useEffect(function(){player.loop=isLooping;},[player,isLooping]);React.useEffect(function(){player.volume=volume;},[player,volume]);React.useEffect(function(){onPlaybackStatusUpdateProp==null||onPlaybackStatusUpdateProp({isPlaying:false,isLoading:true,isBuffering:false,currentPositionMillis:0,durationMillis:0,bufferedDurationMillis:0,isError:false});},[]);React.useEffect(function(){var subscription=player.addListener("playbackStatusUpdate",function(status){var mappedStatus=mapToMediaPlayerStatus(status);onPlaybackStatusUpdateProp==null||onPlaybackStatusUpdateProp(mappedStatus);if(status.isLoaded){if(status.didJustFinish&&!isLooping){onPlaybackFinish==null||onPlaybackFinish();}setIsPlaying(status.playing);}});return function(){return subscription.remove();};},[]);var isFirstSourceRender=React.useRef(true);(0,_MediaPlayerCommon.useSourceDeepCompareEffect)(function(){if(isFirstSourceRender.current){isFirstSourceRender.current=false;return;}player.replace((0,_MediaPlayerCommon.normalizeBase64Source)(source,"audio"));},[source]);var updateAudioMode=React.useCallback((0,_asyncToGenerator2.default)(function*(){try{yield(0,_expoAudio.setAudioModeAsync)({shouldPlayInBackground:playsInBackground,interruptionMode:interruptionMode==="lower volume"?"duckOthers":"doNotMix",playsInSilentMode:playsInSilentModeIOS,shouldRouteThroughEarpiece:playThroughEarpieceAndroid});}catch(e){if((e==null?void 0:e.code)==="E_AUDIO_AUDIOMODE"){console.warn("Background audio playback only works in published apps, not in preview mode. For iOS apps, add 'audio' under UI Background Modes in Project Settings > Apple App Store.");}else{console.error("Failed to set audio mode. interruptionMode, playsInBackground, playsInSilentModeIOS, playThroughEarpieceAndroid might not be set. Failed with",e);}}}),[interruptionMode,playsInBackground,playsInSilentModeIOS,playThroughEarpieceAndroid]);var onTogglePlayback=function onTogglePlayback(){updateAudioMode();};return(0,_jsxRuntime.jsx)(_MediaPlaybackWrapper.default,{ref:ref,isPlaying:isPlaying,player:player,onTogglePlayback:onTogglePlayback});});function mapToMediaPlayerStatus(status){if(status.isLoaded){return{isPlaying:status.playing,isLoading:false,isBuffering:status.isBuffering,currentPositionMillis:status.currentTime*1000,durationMillis:status.duration*1000,bufferedDurationMillis:status.duration*1000,isError:false};}return{isPlaying:false,isLoading:true,isBuffering:false,currentPositionMillis:0,durationMillis:0,bufferedDurationMillis:0,isError:false};}var _default=exports.default=HeadlessAudioPlayer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var React=_interopRequireWildcard(require("react"));var _jsxRuntime=require("react/jsx-runtime");function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap(),t=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(e){return e?t:r;})(e);}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=_getRequireWildcardCache(r);if(t&&t.has(e))return t.get(e);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var u in e)if("default"!==u&&{}.hasOwnProperty.call(e,u)){var i=a?Object.getOwnPropertyDescriptor(e,u):null;i&&(i.get||i.set)?Object.defineProperty(n,u,i):n[u]=e[u];}return n.default=e,t&&t.set(e,n),n;}var MediaPlaybackWrapper=React.forwardRef(function(_ref,ref){var player=_ref.player,isPlaying=_ref.isPlaying,onTogglePlayback=_ref.onTogglePlayback,children=_ref.children;var togglePlayback=React.useCallback(function(){onTogglePlayback==null||onTogglePlayback();if(isPlaying){player==null||player.pause();}else{player==null||player.play();}},[isPlaying,onTogglePlayback]);var pause=React.useCallback(function(){onTogglePlayback==null||onTogglePlayback();player==null||player.pause();},[player,onTogglePlayback]);var play=React.useCallback(function(){onTogglePlayback==null||onTogglePlayback();player==null||player.play();},[player,onTogglePlayback]);var seekToPosition=React.useCallback(function(positionMillis){if(typeof(player==null?void 0:player.seekTo)==="function"){player.seekTo(positionMillis/1000);}else if(player){player.currentTime=positionMillis/1000;}},[player]);React.useImperativeHandle(ref,function(){return{seekToPosition:seekToPosition,togglePlayback:togglePlayback,pause:pause,play:play};},[seekToPosition,togglePlayback,pause,play]);return(0,_jsxRuntime.jsx)(_jsxRuntime.Fragment,{children:children});});var _default=exports.default=MediaPlaybackWrapper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.
|
|
1
|
+
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.normalizeBase64Source=normalizeBase64Source;exports.useSourceDeepCompareEffect=useSourceDeepCompareEffect;exports.useSourceDeepCompareMemoize=useSourceDeepCompareMemoize;var _uuid=require("uuid");var _reactNative=require("react-native");var _react=_interopRequireDefault(require("react"));var URL_REGEX=/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;function normalizeBase64Source(source,type){var uri=source==null?void 0:source.uri;if(_reactNative.Platform.OS==="ios"&&uri&&!uri.match(URL_REGEX)){var _require=require("expo-file-system"),File=_require.File,Paths=_require.Paths;var defaultMimeType=type==="audio"?"wav":"mp4";var mimeType=uri.startsWith(`data:${type}/`)?uri.substring(`data:${type}/`.length,uri.indexOf(";")):defaultMimeType;var file=new File(Paths.cache,`${(0,_uuid.v4)()}.${mimeType.toLowerCase()}`);var base64Content=uri.includes("base64,")?uri.substring(uri.indexOf("base64,")+"base64,".length):uri;file.write(base64Content,{encoding:"base64"});return{uri:file.uri};}return source;}function sourceDeepCompareEquals(a,b){if(a!=null&&a.uri&&b!=null&&b.uri){return a.uri===b.uri;}return a===b;}function useSourceDeepCompareMemoize(value){var ref=_react.default.useRef(undefined);if(!sourceDeepCompareEquals(value,ref.current)){ref.current=value;}return ref.current;}function useSourceDeepCompareEffect(callback,dependencies){_react.default.useEffect(callback,dependencies.map(useSourceDeepCompareMemoize));}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var
|
|
1
|
+
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;exports.mapToMediaPlayerStatus=mapToMediaPlayerStatus;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _objectWithoutProperties2=_interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));var _react=_interopRequireDefault(require("react"));var _reactNative=require("react-native");var _expoVideo=require("expo-video");var _expoAudio=require("expo-audio");var _utilities=require("../../../utilities");var _MediaPlaybackWrapper=_interopRequireDefault(require("../MediaPlaybackWrapper"));var _MediaPlayerCommon=require("../MediaPlayerCommon");var _jsxRuntime=require("react/jsx-runtime");var _excluded=["style","resizeMode","posterResizeMode","posterSource","usePoster","onPlaybackStatusUpdate","onPlaybackFinish","source","playsInSilentModeIOS","isMuted","useNativeControls","shouldPlay","isLooping","positionMillis","allowsFullscreen","rate","volume"];var _this=this,_jsxFileName="/home/runner/work/react-native-jigsaw/react-native-jigsaw/packages/core/src/components/MediaPlayer/VideoPlayer/VideoPlayer.tsx";var VideoPlayer=_react.default.forwardRef(function(_ref,ref){var style=_ref.style,_ref$resizeMode=_ref.resizeMode,resizeMode=_ref$resizeMode===void 0?"contain":_ref$resizeMode,_ref$posterResizeMode=_ref.posterResizeMode,posterResizeMode=_ref$posterResizeMode===void 0?"cover":_ref$posterResizeMode,posterSource=_ref.posterSource,_ref$usePoster=_ref.usePoster,usePoster=_ref$usePoster===void 0?false:_ref$usePoster,onPlaybackStatusUpdateProp=_ref.onPlaybackStatusUpdate,onPlaybackFinish=_ref.onPlaybackFinish,source=_ref.source,_ref$playsInSilentMod=_ref.playsInSilentModeIOS,playsInSilentModeIOS=_ref$playsInSilentMod===void 0?false:_ref$playsInSilentMod,_ref$isMuted=_ref.isMuted,isMuted=_ref$isMuted===void 0?false:_ref$isMuted,_ref$useNativeControl=_ref.useNativeControls,useNativeControls=_ref$useNativeControl===void 0?true:_ref$useNativeControl,_ref$shouldPlay=_ref.shouldPlay,shouldPlay=_ref$shouldPlay===void 0?false:_ref$shouldPlay,_ref$isLooping=_ref.isLooping,isLooping=_ref$isLooping===void 0?false:_ref$isLooping,positionMillis=_ref.positionMillis,_ref$allowsFullscreen=_ref.allowsFullscreen,allowsFullscreen=_ref$allowsFullscreen===void 0?true:_ref$allowsFullscreen,_ref$rate=_ref.rate,rate=_ref$rate===void 0?1:_ref$rate,_ref$volume=_ref.volume,volume=_ref$volume===void 0?1:_ref$volume,rest=(0,_objectWithoutProperties2.default)(_ref,_excluded);var stableSource=(0,_MediaPlayerCommon.useSourceDeepCompareMemoize)((0,_MediaPlayerCommon.normalizeBase64Source)(source,"video"));var player=(0,_expoVideo.useVideoPlayer)(stableSource,function(p){p.loop=isLooping;p.muted=isMuted;p.volume=volume;p.playbackRate=rate;});var videoPlayerRef=_react.default.useRef(null);var _React$useState=_react.default.useState(false),_React$useState2=(0,_slicedToArray2.default)(_React$useState,2),isPlaying=_React$useState2[0],setIsPlaying=_React$useState2[1];var _React$useState3=_react.default.useState(false),_React$useState4=(0,_slicedToArray2.default)(_React$useState3,2),isFullscreen=_React$useState4[0],setIsFullscreen=_React$useState4[1];var _React$useState5=_react.default.useState(usePoster&&!!posterSource),_React$useState6=(0,_slicedToArray2.default)(_React$useState5,2),showPoster=_React$useState6[0],setShowPoster=_React$useState6[1];var mediaPlaybackWrapperRef=_react.default.useRef(null);var sizeStyles=(0,_utilities.extractSizeStyles)(style);_react.default.useEffect(function(){player.muted=isMuted;},[player,isMuted]);_react.default.useEffect(function(){player.loop=isLooping;},[player,isLooping]);_react.default.useEffect(function(){player.volume=volume;},[player,volume]);_react.default.useEffect(function(){player.playbackRate=rate;},[player,rate]);var shouldPlayRef=_react.default.useRef(shouldPlay);var positionMillisRef=_react.default.useRef(positionMillis);shouldPlayRef.current=shouldPlay;positionMillisRef.current=positionMillis;var hasAppliedInitialState=_react.default.useRef(false);_react.default.useEffect(function(){var timeUpdateSub=player.addListener("timeUpdate",function(status){onPlaybackStatusUpdateProp==null||onPlaybackStatusUpdateProp(mapToMediaPlayerStatus(status,player));});var playingChangeSub=player.addListener("playingChange",function(_ref2){var playing=_ref2.isPlaying;setIsPlaying(playing);onPlaybackStatusUpdateProp==null||onPlaybackStatusUpdateProp(mapPlayerToMediaPlayerStatus(player));});var playToEndSub=player.addListener("playToEnd",function(){onPlaybackFinish==null||onPlaybackFinish();});var statusChangeSub=player.addListener("statusChange",function(_ref3){var status=_ref3.status,error=_ref3.error;if(status==="readyToPlay"){setShowPoster(false);if(!hasAppliedInitialState.current){hasAppliedInitialState.current=true;if(positionMillisRef.current){player.currentTime=positionMillisRef.current/1000;}if(shouldPlayRef.current){player.play();}}}var mappedStatus=mapPlayerToMediaPlayerStatus(player);onPlaybackStatusUpdateProp==null||onPlaybackStatusUpdateProp(status==="error"&&error?Object.assign({},mappedStatus,{isError:true,error:error.message}):mappedStatus);});return function(){timeUpdateSub.remove();playingChangeSub.remove();playToEndSub.remove();statusChangeSub.remove();};},[]);var isFirstSourceRender=_react.default.useRef(true);(0,_MediaPlayerCommon.useSourceDeepCompareEffect)(function(){if(isFirstSourceRender.current){isFirstSourceRender.current=false;return;}hasAppliedInitialState.current=false;player.replace((0,_MediaPlayerCommon.normalizeBase64Source)(source,"video"));},[source]);var mappedVideoContentFit;switch(resizeMode){case"contain":mappedVideoContentFit="contain";break;case"cover":mappedVideoContentFit="cover";break;case"stretch":mappedVideoContentFit="fill";break;}var onFullscreenUpdate=function onFullscreenUpdate(type){switch(type){case"entered":setIsFullscreen(true);break;case"exited":setIsFullscreen(false);break;}};var toggleFullscreen=_react.default.useCallback((0,_asyncToGenerator2.default)(function*(){if(videoPlayerRef){if(isFullscreen){var _videoPlayerRef$curre;yield(_videoPlayerRef$curre=videoPlayerRef.current)==null?void 0:_videoPlayerRef$curre.exitFullscreen();}else{var _videoPlayerRef$curre2;yield(_videoPlayerRef$curre2=videoPlayerRef.current)==null?void 0:_videoPlayerRef$curre2.enterFullscreen();}}}),[isFullscreen]);var updateAudioMode=_react.default.useCallback((0,_asyncToGenerator2.default)(function*(){try{yield(0,_expoAudio.setAudioModeAsync)({playsInSilentMode:playsInSilentModeIOS});}catch(e){console.error("Failed to set audio mode. Error details:",e);}}),[playsInSilentModeIOS]);_react.default.useImperativeHandle(ref,function(){var _mediaPlaybackWrapper,_mediaPlaybackWrapper2,_mediaPlaybackWrapper3,_mediaPlaybackWrapper4;return{toggleFullscreen:toggleFullscreen,seekToPosition:((_mediaPlaybackWrapper=mediaPlaybackWrapperRef.current)==null?void 0:_mediaPlaybackWrapper.seekToPosition)||function(){},togglePlayback:((_mediaPlaybackWrapper2=mediaPlaybackWrapperRef.current)==null?void 0:_mediaPlaybackWrapper2.togglePlayback)||function(){},pause:((_mediaPlaybackWrapper3=mediaPlaybackWrapperRef.current)==null?void 0:_mediaPlaybackWrapper3.pause)||function(){},play:((_mediaPlaybackWrapper4=mediaPlaybackWrapperRef.current)==null?void 0:_mediaPlaybackWrapper4.play)||function(){}};},[toggleFullscreen,isPlaying]);return(0,_jsxRuntime.jsx)(_MediaPlaybackWrapper.default,{player:player,isPlaying:isPlaying,ref:mediaPlaybackWrapperRef,onTogglePlayback:updateAudioMode,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[style,styles.container],children:[(0,_jsxRuntime.jsx)(_expoVideo.VideoView,Object.assign({ref:videoPlayerRef,player:player,nativeControls:useNativeControls,style:sizeStyles,contentFit:mappedVideoContentFit,onFullscreenEnter:function onFullscreenEnter(){return onFullscreenUpdate("entered");},onFullscreenExit:function onFullscreenExit(){return onFullscreenUpdate("exited");},allowsFullscreen:allowsFullscreen},rest)),showPoster&&posterSource&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:_reactNative.StyleSheet.absoluteFill,pointerEvents:"none",children:(0,_jsxRuntime.jsx)(_reactNative.Image,{source:posterSource,resizeMode:posterResizeMode,style:[_reactNative.StyleSheet.absoluteFill,sizeStyles]})})]})});});var styles=_reactNative.StyleSheet.create({container:{overflow:"hidden"}});function mapPlayerToMediaPlayerStatus(player){return{isPlaying:player.playing,isLoading:player.status==="loading",isBuffering:player.status==="loading",currentPositionMillis:player.currentTime*1000,durationMillis:player.duration*1000,bufferedDurationMillis:player.bufferedPosition*1000,isError:player.status==="error"};}function mapToMediaPlayerStatus(status,player){return Object.assign({},mapPlayerToMediaPlayerStatus(player),{currentPositionMillis:status.currentTime*1000,bufferedDurationMillis:status.bufferedPosition*1000});}var _default=exports.default=VideoPlayer;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { AudioStatus } from "expo-audio";
|
|
2
3
|
import { HeadlessAudioPlayerProps } from "./AudioPlayerCommon";
|
|
3
|
-
import type { MediaPlayerRef } from "../MediaPlayerCommon";
|
|
4
|
+
import type { MediaPlayerRef, MediaPlayerStatus } from "../MediaPlayerCommon";
|
|
4
5
|
/**
|
|
5
6
|
* Audio Player component without an interface (UI).
|
|
6
7
|
* Only handles playing of the audio and provides callbacks and ref functions
|
|
7
8
|
*/
|
|
8
9
|
declare const HeadlessAudioPlayer: React.ForwardRefExoticComponent<HeadlessAudioPlayerProps & React.RefAttributes<MediaPlayerRef>>;
|
|
10
|
+
export declare function mapToMediaPlayerStatus(status: AudioStatus): MediaPlayerStatus;
|
|
9
11
|
export default HeadlessAudioPlayer;
|
|
@@ -1,37 +1,62 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useAudioPlayer, setAudioModeAsync } from "expo-audio";
|
|
3
|
+
import { normalizeBase64Source, useSourceDeepCompareMemoize, useSourceDeepCompareEffect, } from "../MediaPlayerCommon";
|
|
4
4
|
import MediaPlaybackWrapper from "../MediaPlaybackWrapper";
|
|
5
5
|
/**
|
|
6
6
|
* Audio Player component without an interface (UI).
|
|
7
7
|
* Only handles playing of the audio and provides callbacks and ref functions
|
|
8
8
|
*/
|
|
9
9
|
const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lower volume", playsInBackground = false, playsInSilentModeIOS = false, playThroughEarpieceAndroid = false, onPlaybackStatusUpdate: onPlaybackStatusUpdateProp, onPlaybackFinish, isLooping = false, volume = 1.0, }, ref) => {
|
|
10
|
-
const
|
|
10
|
+
const stableSource = useSourceDeepCompareMemoize(normalizeBase64Source(source, "audio"));
|
|
11
|
+
const player = useAudioPlayer(stableSource);
|
|
11
12
|
const [isPlaying, setIsPlaying] = React.useState(false);
|
|
12
13
|
React.useEffect(() => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}, [
|
|
14
|
+
player.loop = isLooping;
|
|
15
|
+
}, [player, isLooping]);
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
player.volume = volume;
|
|
18
|
+
}, [player, volume]);
|
|
19
|
+
// Emit loading state immediately
|
|
18
20
|
React.useEffect(() => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp({
|
|
22
|
+
isPlaying: false,
|
|
23
|
+
isLoading: true,
|
|
24
|
+
isBuffering: false,
|
|
25
|
+
currentPositionMillis: 0,
|
|
26
|
+
durationMillis: 0,
|
|
27
|
+
bufferedDurationMillis: 0,
|
|
28
|
+
isError: false,
|
|
29
|
+
});
|
|
30
|
+
}, []);
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
const subscription = player.addListener("playbackStatusUpdate", (status) => {
|
|
33
|
+
const mappedStatus = mapToMediaPlayerStatus(status);
|
|
34
|
+
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp(mappedStatus);
|
|
35
|
+
if (status.isLoaded) {
|
|
36
|
+
if (status.didJustFinish && !isLooping) {
|
|
37
|
+
onPlaybackFinish === null || onPlaybackFinish === void 0 ? void 0 : onPlaybackFinish();
|
|
38
|
+
}
|
|
39
|
+
setIsPlaying(status.playing);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return () => subscription.remove();
|
|
43
|
+
}, []);
|
|
44
|
+
// Replace source when it changes (deep comparison on URI to avoid unnecessary reloads)
|
|
45
|
+
const isFirstSourceRender = React.useRef(true);
|
|
46
|
+
useSourceDeepCompareEffect(() => {
|
|
47
|
+
if (isFirstSourceRender.current) {
|
|
48
|
+
isFirstSourceRender.current = false;
|
|
49
|
+
return;
|
|
21
50
|
}
|
|
22
|
-
|
|
51
|
+
player.replace(normalizeBase64Source(source, "audio"));
|
|
52
|
+
}, [source]);
|
|
23
53
|
const updateAudioMode = React.useCallback(async () => {
|
|
24
54
|
try {
|
|
25
|
-
await
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
interruptionModeAndroid: interruptionMode === "lower volume"
|
|
31
|
-
? InterruptionModeAndroid.DuckOthers
|
|
32
|
-
: InterruptionModeAndroid.DoNotMix,
|
|
33
|
-
playsInSilentModeIOS,
|
|
34
|
-
playThroughEarpieceAndroid,
|
|
55
|
+
await setAudioModeAsync({
|
|
56
|
+
shouldPlayInBackground: playsInBackground,
|
|
57
|
+
interruptionMode: interruptionMode === "lower volume" ? "duckOthers" : "doNotMix",
|
|
58
|
+
playsInSilentMode: playsInSilentModeIOS,
|
|
59
|
+
shouldRouteThroughEarpiece: playThroughEarpieceAndroid,
|
|
35
60
|
});
|
|
36
61
|
}
|
|
37
62
|
catch (e) {
|
|
@@ -48,43 +73,33 @@ const HeadlessAudioPlayer = React.forwardRef(({ source, interruptionMode = "lowe
|
|
|
48
73
|
playsInSilentModeIOS,
|
|
49
74
|
playThroughEarpieceAndroid,
|
|
50
75
|
]);
|
|
51
|
-
const onPlaybackStatusUpdate = (status) => {
|
|
52
|
-
const mappedStatus = mapToMediaPlayerStatus(status);
|
|
53
|
-
onPlaybackStatusUpdateProp === null || onPlaybackStatusUpdateProp === void 0 ? void 0 : onPlaybackStatusUpdateProp(mappedStatus);
|
|
54
|
-
if (status.isLoaded) {
|
|
55
|
-
if (status.didJustFinish) {
|
|
56
|
-
if (isLooping) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
onPlaybackFinish === null || onPlaybackFinish === void 0 ? void 0 : onPlaybackFinish();
|
|
60
|
-
}
|
|
61
|
-
setIsPlaying(status.isPlaying);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
76
|
const onTogglePlayback = () => {
|
|
65
|
-
//Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
77
|
+
// Has to be called everytime a player is played to reconfigure the global Audio config based on each player's configuration
|
|
66
78
|
updateAudioMode();
|
|
67
79
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
return (React.createElement(MediaPlaybackWrapper, { ref: ref, isPlaying: isPlaying, player: player, onTogglePlayback: onTogglePlayback }));
|
|
81
|
+
});
|
|
82
|
+
export function mapToMediaPlayerStatus(status) {
|
|
83
|
+
if (status.isLoaded) {
|
|
84
|
+
return {
|
|
85
|
+
isPlaying: status.playing,
|
|
86
|
+
isLoading: false,
|
|
87
|
+
isBuffering: status.isBuffering,
|
|
88
|
+
currentPositionMillis: status.currentTime * 1000,
|
|
89
|
+
durationMillis: status.duration * 1000,
|
|
90
|
+
bufferedDurationMillis: status.duration * 1000,
|
|
76
91
|
isError: false,
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
isPlaying: false,
|
|
96
|
+
isLoading: true,
|
|
97
|
+
isBuffering: false,
|
|
98
|
+
currentPositionMillis: 0,
|
|
99
|
+
durationMillis: 0,
|
|
100
|
+
bufferedDurationMillis: 0,
|
|
101
|
+
isError: false,
|
|
82
102
|
};
|
|
83
|
-
|
|
84
|
-
loadAudio();
|
|
85
|
-
// Ignore dependency of loadAudio
|
|
86
|
-
}, [source]);
|
|
87
|
-
return (React.createElement(MediaPlaybackWrapper, { ref: ref, isPlaying: isPlaying, media: currentSound, onTogglePlayback: onTogglePlayback }));
|
|
88
|
-
});
|
|
103
|
+
}
|
|
89
104
|
export default HeadlessAudioPlayer;
|
|
90
105
|
//# sourceMappingURL=HeadlessAudioPlayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeadlessAudioPlayer.js","sourceRoot":"","sources":["../../../../../../src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,
|
|
1
|
+
{"version":3,"file":"HeadlessAudioPlayer.js","sourceRoot":"","sources":["../../../../../../src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type { AudioPlayer } from "expo-audio";
|
|
3
|
+
import type { VideoPlayer } from "expo-video";
|
|
3
4
|
import type { MediaPlayerRef } from "./MediaPlayerCommon";
|
|
4
5
|
interface MediaPlaybackWrapperProps {
|
|
5
|
-
|
|
6
|
+
player?: AudioPlayer | VideoPlayer;
|
|
6
7
|
isPlaying?: boolean;
|
|
7
8
|
onTogglePlayback?: () => void;
|
|
8
9
|
}
|
|
@@ -2,34 +2,32 @@ import * as React from "react";
|
|
|
2
2
|
/**
|
|
3
3
|
* Wrapper component that handles common media playback operations that is reusable with audio and video players
|
|
4
4
|
*/
|
|
5
|
-
const MediaPlaybackWrapper = React.forwardRef(({
|
|
6
|
-
const togglePlayback = React.useCallback(
|
|
5
|
+
const MediaPlaybackWrapper = React.forwardRef(({ player, isPlaying, onTogglePlayback, children }, ref) => {
|
|
6
|
+
const togglePlayback = React.useCallback(() => {
|
|
7
7
|
onTogglePlayback === null || onTogglePlayback === void 0 ? void 0 : onTogglePlayback();
|
|
8
8
|
if (isPlaying) {
|
|
9
|
-
|
|
9
|
+
player === null || player === void 0 ? void 0 : player.pause();
|
|
10
10
|
}
|
|
11
11
|
else {
|
|
12
|
-
|
|
12
|
+
player === null || player === void 0 ? void 0 : player.play();
|
|
13
13
|
}
|
|
14
|
-
}, [
|
|
15
|
-
const pause = React.useCallback(
|
|
14
|
+
}, [isPlaying, onTogglePlayback]);
|
|
15
|
+
const pause = React.useCallback(() => {
|
|
16
16
|
onTogglePlayback === null || onTogglePlayback === void 0 ? void 0 : onTogglePlayback();
|
|
17
|
-
|
|
18
|
-
}, [
|
|
19
|
-
const play = React.useCallback(
|
|
17
|
+
player === null || player === void 0 ? void 0 : player.pause();
|
|
18
|
+
}, [player, onTogglePlayback]);
|
|
19
|
+
const play = React.useCallback(() => {
|
|
20
20
|
onTogglePlayback === null || onTogglePlayback === void 0 ? void 0 : onTogglePlayback();
|
|
21
|
-
|
|
22
|
-
}, [
|
|
23
|
-
const seekToPosition = React.useCallback(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
: undefined;
|
|
32
|
-
}, [media]);
|
|
21
|
+
player === null || player === void 0 ? void 0 : player.play();
|
|
22
|
+
}, [player, onTogglePlayback]);
|
|
23
|
+
const seekToPosition = React.useCallback((positionMillis) => {
|
|
24
|
+
if (typeof (player === null || player === void 0 ? void 0 : player.seekTo) === "function") {
|
|
25
|
+
player.seekTo(positionMillis / 1000);
|
|
26
|
+
}
|
|
27
|
+
else if (player) {
|
|
28
|
+
player.currentTime = positionMillis / 1000;
|
|
29
|
+
}
|
|
30
|
+
}, [player]);
|
|
33
31
|
React.useImperativeHandle(ref, () => ({
|
|
34
32
|
seekToPosition,
|
|
35
33
|
togglePlayback,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaPlaybackWrapper.js","sourceRoot":"","sources":["../../../../../src/components/MediaPlayer/MediaPlaybackWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MediaPlaybackWrapper.js","sourceRoot":"","sources":["../../../../../src/components/MediaPlayer/MediaPlaybackWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B;;GAEG;AACH,MAAM,oBAAoB,GAAG,KAAK,CAAC,UAAU,CAG3C,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5C,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAC;QAErB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAE,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,EAAE,CAAC;QACjB,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAElC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACnC,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAC;QACrB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAE,CAAC;IAClB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAClC,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAC;QACrB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE/B,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,cAAsB,EAAE,EAAE;QACzB,IAAI,OAAO,CAAC,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,MAAM,CAAA,KAAK,UAAU,EAAE,CAAC;YACjD,MAAsB,CAAC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,CAAC,WAAW,GAAG,cAAc,GAAG,IAAI,CAAC;QAC7C,CAAC;IACH,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,KAAK,CAAC,mBAAmB,CACvB,GAAG,EACH,GAAG,EAAE,CAAC,CAAC;QACL,cAAc;QACd,cAAc;QACd,KAAK;QACL,IAAI;KACL,CAAC,EACF,CAAC,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,CAC9C,CAAC;IAEF,OAAO,0CAAG,QAAQ,CAAI,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AudioSource } from "expo-audio";
|
|
2
|
+
import { VideoSource } from "expo-video";
|
|
2
3
|
import React from "react";
|
|
3
4
|
export interface MediaPlayerStatus {
|
|
4
5
|
isPlaying: boolean;
|
|
@@ -19,11 +20,11 @@ export interface MediaPlayerRef {
|
|
|
19
20
|
export interface MediaPlayerProps {
|
|
20
21
|
onPlaybackStatusUpdate?: (status: MediaPlayerStatus) => void;
|
|
21
22
|
onPlaybackFinish?: () => void;
|
|
22
|
-
source:
|
|
23
|
+
source: AudioSource | VideoSource;
|
|
23
24
|
}
|
|
24
|
-
export declare function mapToMediaPlayerStatus(status: AVPlaybackStatus): MediaPlayerStatus;
|
|
25
25
|
/**
|
|
26
26
|
* Base64 strings are not playable on iOS and needs to be saved to a file before playing
|
|
27
27
|
*/
|
|
28
|
-
export declare function normalizeBase64Source(source:
|
|
28
|
+
export declare function normalizeBase64Source(source: AudioSource | VideoSource, type: "audio" | "video"): AudioSource | VideoSource;
|
|
29
|
+
export declare function useSourceDeepCompareMemoize(value: any): any;
|
|
29
30
|
export declare function useSourceDeepCompareEffect(callback: React.EffectCallback, dependencies: React.DependencyList): void;
|
|
@@ -1,37 +1,14 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
import { Platform } from "react-native";
|
|
3
3
|
import React from "react";
|
|
4
|
-
export function mapToMediaPlayerStatus(status) {
|
|
5
|
-
if (status.isLoaded) {
|
|
6
|
-
return {
|
|
7
|
-
isPlaying: status.isPlaying,
|
|
8
|
-
isLoading: false,
|
|
9
|
-
isBuffering: status.isBuffering,
|
|
10
|
-
currentPositionMillis: status.positionMillis || 0,
|
|
11
|
-
durationMillis: status.durationMillis || 0,
|
|
12
|
-
bufferedDurationMillis: status.playableDurationMillis || 0,
|
|
13
|
-
isError: false,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
return {
|
|
17
|
-
isPlaying: false,
|
|
18
|
-
isLoading: false,
|
|
19
|
-
isBuffering: false,
|
|
20
|
-
currentPositionMillis: 0,
|
|
21
|
-
durationMillis: 0,
|
|
22
|
-
bufferedDurationMillis: 0,
|
|
23
|
-
isError: true,
|
|
24
|
-
error: status.error,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
4
|
const URL_REGEX = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
|
|
28
5
|
/**
|
|
29
6
|
* Base64 strings are not playable on iOS and needs to be saved to a file before playing
|
|
30
7
|
*/
|
|
31
|
-
export
|
|
8
|
+
export function normalizeBase64Source(source, type) {
|
|
32
9
|
const uri = source === null || source === void 0 ? void 0 : source.uri;
|
|
33
10
|
if (Platform.OS === "ios" && uri && !uri.match(URL_REGEX)) {
|
|
34
|
-
const { File, Paths } =
|
|
11
|
+
const { File, Paths } = require("expo-file-system");
|
|
35
12
|
const defaultMimeType = type === "audio" ? "wav" : "mp4";
|
|
36
13
|
const mimeType = uri.startsWith(`data:${type}/`)
|
|
37
14
|
? uri.substring(`data:${type}/`.length, uri.indexOf(";")) //Ex: extract 'mp4' from 'data:video/mp4;base64,....'
|
|
@@ -57,7 +34,7 @@ function sourceDeepCompareEquals(a, b) {
|
|
|
57
34
|
}
|
|
58
35
|
return a === b;
|
|
59
36
|
}
|
|
60
|
-
function useSourceDeepCompareMemoize(value) {
|
|
37
|
+
export function useSourceDeepCompareMemoize(value) {
|
|
61
38
|
const ref = React.useRef(undefined);
|
|
62
39
|
if (!sourceDeepCompareEquals(value, ref.current)) {
|
|
63
40
|
ref.current = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaPlayerCommon.js","sourceRoot":"","sources":["../../../../../src/components/MediaPlayer/MediaPlayerCommon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MediaPlayerCommon.js","sourceRoot":"","sources":["../../../../../src/components/MediaPlayer/MediaPlayerCommon.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,MAAM,SAAS,GACb,oFAAoF,CAAC;AAEvF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAiC,EACjC,IAAuB;IAEvB,MAAM,GAAG,GAAwB,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,GAAG,CAAC;IAErD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAEpD,MAAM,eAAe,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QACzD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,IAAI,GAAG,CAAC;YAC9C,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,qDAAqD;YAC/G,CAAC,CAAC,eAAe,CAAC;QAEpB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAE1E,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC3C,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,uCAAuC;YAClG,CAAC,CAAC,GAAG,CAAC;QAER,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,2IAA2I;AAC3I,0DAA0D;AAC1D,EAAE;AACF,kHAAkH;AAClH,gDAAgD;AAChD,SAAS,uBAAuB,CAAC,CAAM,EAAE,CAAM;IAC7C,IAAI,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,GAAG,MAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,GAAG,CAAA,EAAE,CAAC;QACrB,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAU;IACpD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAM,SAAS,CAAC,CAAC;IACzC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,QAA8B,EAC9B,YAAkC;IAElC,uDAAuD;IACvD,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { ImageResizeMode } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
import type { MediaPlayerRef, MediaPlayerProps } from "../MediaPlayerCommon";
|
|
2
|
+
import { ImageProps, ImageResizeMode } from "react-native";
|
|
3
|
+
import { VideoViewProps as ExpoVideoProps, TimeUpdateEventPayload, VideoPlayer as VideoPlayerType } from "expo-video";
|
|
4
|
+
import type { MediaPlayerRef, MediaPlayerProps, MediaPlayerStatus } from "../MediaPlayerCommon";
|
|
5
5
|
type ResizeMode = "contain" | "cover" | "stretch";
|
|
6
|
-
type ExpoVideoPropsOmitted = Omit<ExpoVideoProps, "
|
|
6
|
+
type ExpoVideoPropsOmitted = Omit<ExpoVideoProps, "player" | "nativeControls">;
|
|
7
7
|
interface VideoPlayerProps extends ExpoVideoPropsOmitted, MediaPlayerProps {
|
|
8
8
|
resizeMode?: ResizeMode;
|
|
9
9
|
posterResizeMode?: ImageResizeMode;
|
|
10
|
+
posterSource?: ImageProps["source"];
|
|
11
|
+
usePoster?: boolean;
|
|
10
12
|
playsInSilentModeIOS?: boolean;
|
|
13
|
+
isMuted?: boolean;
|
|
14
|
+
useNativeControls?: boolean;
|
|
15
|
+
shouldPlay?: boolean;
|
|
16
|
+
isLooping?: boolean;
|
|
17
|
+
positionMillis?: number;
|
|
18
|
+
rate?: number;
|
|
19
|
+
volume?: number;
|
|
11
20
|
}
|
|
12
21
|
export interface VideoPlayerRef extends MediaPlayerRef {
|
|
13
22
|
toggleFullscreen: () => void;
|
|
14
23
|
}
|
|
15
24
|
declare const VideoPlayer: React.ForwardRefExoticComponent<VideoPlayerProps & React.RefAttributes<VideoPlayerRef>>;
|
|
25
|
+
export declare function mapToMediaPlayerStatus(status: TimeUpdateEventPayload, player: VideoPlayerType): MediaPlayerStatus;
|
|
16
26
|
export default VideoPlayer;
|