UNPKG

@azzapp/react-native-skia-video

Version:
112 lines (110 loc) 3.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useVideoCompositionPlayer = void 0; var _reactNativeSkia = require("@shopify/react-native-skia"); var _reactNativeReanimated = require("react-native-reanimated"); var _react = require("react"); var _RNSkiaVideoModule = _interopRequireDefault(require("./RNSkiaVideoModule")); var _useEventListener = _interopRequireDefault(require("./utils/useEventListener")); var _reactNative = require("react-native"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * A hook that creates a video composition player. */ const useVideoCompositionPlayer = ({ composition, drawFrame, beforeDrawFrame, afterDrawFrame, width, height, autoPlay = false, isLooping = false, onReadyToPlay, onComplete, onError }) => { const [isErrored, setIsErrored] = (0, _react.useState)(false); const framesExtractor = (0, _react.useMemo)(() => { if (composition && !isErrored) { return _RNSkiaVideoModule.default.createVideoCompositionFramesExtractor(composition); } return null; }, [isErrored, composition]); (0, _react.useEffect)(() => { (0, _reactNativeReanimated.runOnUI)(() => { framesExtractor?.prepare(); })(); }, [framesExtractor]); const currentFrame = (0, _reactNativeReanimated.useSharedValue)(null); (0, _react.useEffect)(() => () => { currentFrame.value = null; framesExtractor?.dispose(); }, [currentFrame, framesExtractor]); const retry = (0, _react.useCallback)(() => { setIsErrored(false); }, []); const errorHandler = (0, _react.useCallback)(error => { onError?.(error, retry); setIsErrored(true); }, [onError, retry]); (0, _react.useEffect)(() => { if (framesExtractor) { framesExtractor.isLooping = isLooping; } }, [framesExtractor, isLooping]); (0, _useEventListener.default)(framesExtractor, 'ready', onReadyToPlay); (0, _useEventListener.default)(framesExtractor, 'complete', onComplete); (0, _useEventListener.default)(framesExtractor, 'error', errorHandler); (0, _react.useEffect)(() => { if (autoPlay) { framesExtractor?.play(); } }, [framesExtractor, autoPlay]); const surfaceSharedValue = (0, _reactNativeReanimated.useSharedValue)(null); const pixelRatio = _reactNative.PixelRatio.get(); (0, _reactNativeReanimated.useFrameCallback)(() => { 'worklet'; if (!framesExtractor) { return; } let surface = surfaceSharedValue.value; if (!surface) { surface = _reactNativeSkia.Skia.Surface.MakeOffscreen(width * pixelRatio, height * pixelRatio); surfaceSharedValue.value = surface; } if (!surface) { console.warn('Failed to create surface'); return; } const canvas = surface.getCanvas(); const context = beforeDrawFrame?.(); drawFrame({ canvas, context, videoComposition: composition, currentTime: framesExtractor.currentTime, frames: framesExtractor.decodeCompositionFrames(), width: width * pixelRatio, height: height * pixelRatio }); surface.flush(); const previousFrame = currentFrame.value; try { currentFrame.value = _reactNativeSkia.Skia.Image.MakeImageFromNativeTextureUnstable(surface.getNativeTextureUnstable(), width * pixelRatio, height * pixelRatio); } catch (error) { console.warn('Failed to create image from texture', error); return; } previousFrame?.dispose(); afterDrawFrame?.(context); }, true); return { currentFrame, player: framesExtractor }; }; exports.useVideoCompositionPlayer = useVideoCompositionPlayer; //# sourceMappingURL=videoCompositionPlayer.js.map