UNPKG

@azzapp/react-native-skia-video

Version:
101 lines (97 loc) 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.exportVideoComposition = void 0; var _reactNativeReanimated = require("react-native-reanimated"); var _reactNative = require("react-native"); var _reactNativeSkia = require("@shopify/react-native-skia"); var _RNSkiaVideoModule = _interopRequireDefault(require("./RNSkiaVideoModule")); var _thread = require("./utils/thread"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const Promise = global.Promise; const OS = _reactNative.Platform.OS; /** * Exports a video composition to a video file. * * @returns A promise that resolves when the export is complete. */ const exportVideoComposition = async ({ videoComposition, drawFrame, beforeDrawFrame, afterDrawFrame, onProgress, ...options }) => new Promise((resolve, reject) => { (0, _thread.runOnNewThread)(() => { 'worklet'; let surface = null; let frameExtractor = null; let encoder = null; const { width, height } = options; try { surface = _reactNativeSkia.Skia.Surface.MakeOffscreen(width, height); if (!surface) { throw new Error('Failed to create Skia surface'); } encoder = _RNSkiaVideoModule.default.createVideoEncoder(options); encoder.prepare(); frameExtractor = _RNSkiaVideoModule.default.createVideoCompositionFramesExtractorSync(videoComposition); frameExtractor.start(); const nbFrames = videoComposition.duration * options.frameRate; const canvas = surface.getCanvas(); const clearColor = _reactNativeSkia.Skia.Color('#00000000'); for (let i = 0; i < nbFrames; i++) { const currentTime = i / options.frameRate; const frames = frameExtractor.decodeCompositionFrames(currentTime); canvas.drawColor(clearColor, _reactNativeSkia.BlendMode.Clear); const context = beforeDrawFrame?.(); drawFrame({ context, canvas, videoComposition, currentTime, frames, width: options.width, height: options.height }); surface.flush(); // On iOS and macOS, the first flush is not synchronous, // so we need to wait for the next frame if (i === 0 && (OS === 'ios' || OS === 'macos')) { _RNSkiaVideoModule.default.usleep?.(1000); } const texture = surface.getNativeTextureUnstable(); encoder.encodeFrame(texture, currentTime); afterDrawFrame?.(context); if (onProgress) { (0, _reactNativeReanimated.runOnJS)(onProgress)({ framesCompleted: i + 1, nbFrames }); } } } catch (e) { (0, _reactNativeReanimated.runOnJS)(reject)(e); return; } finally { frameExtractor?.dispose(); surface?.dispose(); } try { encoder.finishWriting(); } catch (e) { (0, _reactNativeReanimated.runOnJS)(reject)(e); return; } finally { encoder?.dispose(); } (0, _reactNativeReanimated.runOnJS)(resolve)(); }); }); exports.exportVideoComposition = exportVideoComposition; //# sourceMappingURL=exportVideoComposition.js.map