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