UNPKG

molstar

Version:

A comprehensive macromolecular library.

115 lines 6.1 kB
/** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { __assign, __awaiter, __generator } from "tslib"; import * as HME from 'h264-mp4-encoder'; import { PluginStateAnimation } from '../../mol-plugin-state/animation/model'; export function encodeMp4Animation(plugin, ctx, params) { var _a, _b, _c; return __awaiter(this, void 0, void 0, function () { var durationMs, encoder, width, height, vw, vh, normalizedViewport, loop, canvasProps, wasAnimating, stoppedAnimation, finalized, fps, N, dt, i, image; return __generator(this, function (_d) { switch (_d.label) { case 0: return [4 /*yield*/, ctx.update({ message: 'Initializing...', isIndeterminate: true })]; case 1: _d.sent(); validateViewport(params); durationMs = PluginStateAnimation.getDuration(plugin, params.animation); if (durationMs === void 0) { throw new Error('The animation does not have the duration specified.'); } return [4 /*yield*/, HME.createH264MP4Encoder()]; case 2: encoder = _d.sent(); width = params.width, height = params.height; vw = params.viewport.width, vh = params.viewport.height; // dimensions must be a multiple of 2 if (vw % 2 !== 0) vw -= 1; if (vh % 2 !== 0) vh -= 1; normalizedViewport = __assign(__assign({}, params.viewport), { width: vw, height: vh }); encoder.width = vw; encoder.height = vh; if (params.quantizationParameter) encoder.quantizationParameter = params.quantizationParameter; if (params.fps) encoder.frameRate = params.fps; encoder.initialize(); loop = plugin.animationLoop; canvasProps = (_a = plugin.canvas3d) === null || _a === void 0 ? void 0 : _a.props; wasAnimating = loop.isAnimating; stoppedAnimation = true, finalized = false; _d.label = 3; case 3: _d.trys.push([3, , 13, 16]); loop.stop(); loop.resetTime(0); if (params.customBackground !== void 0) { (_b = plugin.canvas3d) === null || _b === void 0 ? void 0 : _b.setProps({ renderer: { backgroundColor: params.customBackground }, transparentBackground: false }, true); } fps = encoder.frameRate; N = Math.ceil(durationMs / 1000 * fps); dt = durationMs / N; return [4 /*yield*/, ctx.update({ message: 'Rendering...', isIndeterminate: false, current: 0, max: N + 1 })]; case 4: _d.sent(); return [4 /*yield*/, plugin.managers.animation.play(params.animation.definition, params.animation.params)]; case 5: _d.sent(); stoppedAnimation = false; i = 0; _d.label = 6; case 6: if (!(i <= N)) return [3 /*break*/, 10]; return [4 /*yield*/, loop.tick(i * dt, { isSynchronous: true, manualDraw: true })]; case 7: _d.sent(); image = params.pass.getImageData(width, height, normalizedViewport); encoder.addFrameRgba(image.data); if (!ctx.shouldUpdate) return [3 /*break*/, 9]; return [4 /*yield*/, ctx.update({ current: i + 1 })]; case 8: _d.sent(); _d.label = 9; case 9: i++; return [3 /*break*/, 6]; case 10: return [4 /*yield*/, ctx.update({ message: 'Applying finishing touches...', isIndeterminate: true })]; case 11: _d.sent(); return [4 /*yield*/, plugin.managers.animation.stop()]; case 12: _d.sent(); stoppedAnimation = true; encoder.finalize(); finalized = true; return [2 /*return*/, encoder.FS.readFile(encoder.outputFilename)]; case 13: if (finalized) encoder.delete(); if (params.customBackground !== void 0) { (_c = plugin.canvas3d) === null || _c === void 0 ? void 0 : _c.setProps({ renderer: { backgroundColor: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.renderer.backgroundColor }, transparentBackground: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.transparentBackground }); } if (!!stoppedAnimation) return [3 /*break*/, 15]; return [4 /*yield*/, plugin.managers.animation.stop()]; case 14: _d.sent(); _d.label = 15; case 15: if (wasAnimating) loop.start(); return [7 /*endfinally*/]; case 16: return [2 /*return*/]; } }); }); } function validateViewport(params) { if (params.viewport.x + params.viewport.width > params.width || params.viewport.y + params.viewport.height > params.height) { throw new Error('Viewport exceeds the canvas dimensions.'); } } //# sourceMappingURL=encoder.js.map