polotno-node 2.15.7 → 2.15.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-CBBKKHN5.js +65 -0
- package/dist/assets/index-DAfiosIl.js +444 -0
- package/dist/assets/{index.es-DhuWYA8x.js → index.es-B5plNUjz.js} +2 -2
- package/dist/assets/jspdf.es.min-BuG4Ttcb.js +79 -0
- package/dist/index.html +1 -1
- package/instance.js +82 -10
- package/package.json +8 -8
- package/dist/assets/index-A296L9Ae.js +0 -521
- package/dist/assets/index-DUf3mRG9.js +0 -65
package/dist/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
}
|
|
9
9
|
</style>
|
|
10
10
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-DAfiosIl.js"></script>
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/instance.js
CHANGED
|
@@ -2,6 +2,7 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const crypto = require('crypto');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
5
6
|
const { pathToFileURL } = require('url');
|
|
6
7
|
const { Readable } = require('stream');
|
|
7
8
|
const { pipeline } = require('stream/promises');
|
|
@@ -603,8 +604,34 @@ module.exports.createInstance = async ({
|
|
|
603
604
|
return blob;
|
|
604
605
|
};
|
|
605
606
|
|
|
606
|
-
const
|
|
607
|
-
|
|
607
|
+
const isFfmpegAvailable = () => {
|
|
608
|
+
try {
|
|
609
|
+
execSync('ffmpeg -version', { stdio: 'ignore' });
|
|
610
|
+
return true;
|
|
611
|
+
} catch {
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
const getAudioCodec = (filePath) => {
|
|
617
|
+
try {
|
|
618
|
+
const result = execSync(
|
|
619
|
+
`ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "${filePath}"`,
|
|
620
|
+
{ encoding: 'utf8' }
|
|
621
|
+
);
|
|
622
|
+
return result.trim();
|
|
623
|
+
} catch {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
const convertAudioToAac = (inputPath, outputPath) => {
|
|
629
|
+
execSync(`ffmpeg -y -i "${inputPath}" -c:v copy -c:a aac "${outputPath}"`, {
|
|
630
|
+
stdio: 'ignore',
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const jsonToVideoFile = async (json, outputPath, attrs = {}) => {
|
|
608
635
|
const shouldDownloadMedia =
|
|
609
636
|
!hasCustomClientUrl && !(attrs && attrs.skipDownloads);
|
|
610
637
|
|
|
@@ -612,6 +639,8 @@ module.exports.createInstance = async ({
|
|
|
612
639
|
? await prepareLocalMediaForVideoExport(json)
|
|
613
640
|
: { json, cleanup: async () => {} };
|
|
614
641
|
|
|
642
|
+
const writeStream = fs.createWriteStream(outputPath);
|
|
643
|
+
|
|
615
644
|
try {
|
|
616
645
|
const mimeType = await run(
|
|
617
646
|
async (json, attrs) => {
|
|
@@ -639,13 +668,13 @@ module.exports.createInstance = async ({
|
|
|
639
668
|
// to ensure text fits properly in animations. User preferences are ignored for now.
|
|
640
669
|
window.config.setTextOverflow('resize');
|
|
641
670
|
|
|
642
|
-
if (!window.
|
|
671
|
+
if (!window.__polotnoLoadVideoExport) {
|
|
643
672
|
throw new Error(
|
|
644
|
-
'Video export module loader is not defined in the client. Expected window.
|
|
673
|
+
'Video export module loader is not defined in the client. Expected window.__polotnoLoadVideoExport().'
|
|
645
674
|
);
|
|
646
675
|
}
|
|
647
676
|
|
|
648
|
-
const { storeToVideo } = await window.
|
|
677
|
+
const { storeToVideo } = await window.__polotnoLoadVideoExport();
|
|
649
678
|
|
|
650
679
|
// Create abort controller to cancel video render on error
|
|
651
680
|
const abortController = new AbortController();
|
|
@@ -708,7 +737,7 @@ module.exports.createInstance = async ({
|
|
|
708
737
|
for (let i = 0; i < chunk.length; i++) {
|
|
709
738
|
binary += String.fromCharCode(chunk[i]);
|
|
710
739
|
}
|
|
711
|
-
await window.
|
|
740
|
+
await window.__polotnoWriteChunk(btoa(binary));
|
|
712
741
|
}
|
|
713
742
|
|
|
714
743
|
return videoBlob.type;
|
|
@@ -717,19 +746,61 @@ module.exports.createInstance = async ({
|
|
|
717
746
|
{
|
|
718
747
|
...attrs,
|
|
719
748
|
exposeFunctions: {
|
|
720
|
-
|
|
749
|
+
__polotnoWriteChunk: (base64Chunk) => {
|
|
750
|
+
const buffer = Buffer.from(base64Chunk, 'base64');
|
|
751
|
+
writeStream.write(buffer);
|
|
752
|
+
},
|
|
721
753
|
},
|
|
722
754
|
}
|
|
723
755
|
);
|
|
724
|
-
|
|
756
|
+
|
|
757
|
+
writeStream.end();
|
|
758
|
+
await new Promise((resolve) => writeStream.on('finish', resolve));
|
|
759
|
+
|
|
760
|
+
// Convert audio to AAC if needed
|
|
761
|
+
if (isFfmpegAvailable()) {
|
|
762
|
+
const codec = getAudioCodec(outputPath);
|
|
763
|
+
if (codec && codec !== 'aac') {
|
|
764
|
+
const tempPath = outputPath + '.tmp.mp4';
|
|
765
|
+
convertAudioToAac(outputPath, tempPath);
|
|
766
|
+
await fs.promises.rename(tempPath, outputPath);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return mimeType;
|
|
725
771
|
} finally {
|
|
726
772
|
await prepared.cleanup();
|
|
727
773
|
}
|
|
728
774
|
};
|
|
729
775
|
|
|
776
|
+
const jsonToVideoDataURL = async (json, attrs) => {
|
|
777
|
+
const tempPath = path.join(
|
|
778
|
+
os.tmpdir(),
|
|
779
|
+
`polotno-video-${Date.now()}-${Math.random().toString(36).slice(2)}.mp4`
|
|
780
|
+
);
|
|
781
|
+
try {
|
|
782
|
+
const mimeType = await jsonToVideoFile(json, tempPath, attrs);
|
|
783
|
+
const buffer = await fs.promises.readFile(tempPath);
|
|
784
|
+
return `data:${mimeType || 'video/mp4'};base64,${buffer.toString(
|
|
785
|
+
'base64'
|
|
786
|
+
)}`;
|
|
787
|
+
} finally {
|
|
788
|
+
await fs.promises.rm(tempPath, { force: true });
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
|
|
730
792
|
const jsonToVideoBase64 = async (json, attrs) => {
|
|
731
|
-
const
|
|
732
|
-
|
|
793
|
+
const tempPath = path.join(
|
|
794
|
+
os.tmpdir(),
|
|
795
|
+
`polotno-video-${Date.now()}-${Math.random().toString(36).slice(2)}.mp4`
|
|
796
|
+
);
|
|
797
|
+
try {
|
|
798
|
+
await jsonToVideoFile(json, tempPath, attrs);
|
|
799
|
+
const buffer = await fs.promises.readFile(tempPath);
|
|
800
|
+
return buffer.toString('base64');
|
|
801
|
+
} finally {
|
|
802
|
+
await fs.promises.rm(tempPath, { force: true });
|
|
803
|
+
}
|
|
733
804
|
};
|
|
734
805
|
|
|
735
806
|
const instance = {
|
|
@@ -749,6 +820,7 @@ module.exports.createInstance = async ({
|
|
|
749
820
|
jsonToGIFBase64,
|
|
750
821
|
jsonToVideoDataURL,
|
|
751
822
|
jsonToVideoBase64,
|
|
823
|
+
jsonToVideoFile,
|
|
752
824
|
createPage: async () =>
|
|
753
825
|
await module.exports.createPage(browser, visitPage, requestInterceptor),
|
|
754
826
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polotno-node",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.9",
|
|
4
4
|
"description": "Polotno workflow from NodeJS",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -23,26 +23,26 @@
|
|
|
23
23
|
"browserslist": "> 0.5%, last 2 versions, not dead",
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@polotno/video-export": "^0.0.11",
|
|
26
|
-
"axios": "^1.13.
|
|
27
|
-
"dotenv": "^17.2.
|
|
26
|
+
"axios": "^1.13.4",
|
|
27
|
+
"dotenv": "^17.2.4",
|
|
28
28
|
"fluent-ffmpeg": "^2.1.3",
|
|
29
|
-
"jspdf": "^4.
|
|
29
|
+
"jspdf": "^4.1.0",
|
|
30
30
|
"patch-package": "^8.0.1",
|
|
31
31
|
"pixelmatch": "^7.1.0",
|
|
32
32
|
"pngjs": "^7.0.0",
|
|
33
|
-
"polotno": "^2.
|
|
33
|
+
"polotno": "^2.36.0",
|
|
34
34
|
"react": "^18.3.1",
|
|
35
35
|
"react-dom": "^18.3.1",
|
|
36
36
|
"vite": "^7.3.1",
|
|
37
|
-
"vitest": "^4.0.
|
|
37
|
+
"vitest": "^4.0.18",
|
|
38
38
|
"web-audio-api": "^0.2.2"
|
|
39
39
|
},
|
|
40
40
|
"author": "Anton Lavrenov",
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@sparticuz/chromium": "^143.0.4",
|
|
44
|
-
"puppeteer": "24.
|
|
45
|
-
"puppeteer-core": "24.
|
|
44
|
+
"puppeteer": "24.37.2",
|
|
45
|
+
"puppeteer-core": "24.37.2",
|
|
46
46
|
"tmp": "^0.2.5"
|
|
47
47
|
},
|
|
48
48
|
"bugs": {
|