@azzapp/react-native-skia-video
Version:
video support for react-native-skia
112 lines (110 loc) • 3.72 kB
JavaScript
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
;