larkup 0.1.45 → 0.1.47
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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +12 -12
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +16 -16
- package/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
- package/.next/server/app/analytics.html +1 -1
- package/.next/server/app/analytics.rsc +17 -17
- package/.next/server/app/analytics.segments/_full.segment.rsc +17 -17
- package/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
- package/.next/server/app/analytics.segments/_index.segment.rsc +11 -11
- package/.next/server/app/analytics.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
- package/.next/server/app/api/chat/route.js +9 -9
- package/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/.next/server/app/api/deploy/ssh/route.js +2 -2
- package/.next/server/app/api/deploy/ssh/route.js.nft.json +1 -1
- package/.next/server/app/api/doc-editor/edit/route.js +2 -2
- package/.next/server/app/api/doc-editor/export/route.js +2 -2
- package/.next/server/app/api/doc-editor/extract-text/route.js +2 -2
- package/.next/server/app/api/doc-editor/parse/route.js +1 -1
- package/.next/server/app/api/doc-editor/restore/route.js +2 -2
- package/.next/server/app/api/document/sign/route.js +3 -3
- package/.next/server/app/api/marketplace/[toolId]/route.js.nft.json +1 -1
- package/.next/server/app/api/marketplace/route.js.nft.json +1 -1
- package/.next/server/app/api/media/process/route.js.nft.json +1 -1
- package/.next/server/app/api/media/route.js.nft.json +1 -1
- package/.next/server/app/api/parse-file/route.js +2 -2
- package/.next/server/app/api/server/download/route.js +1 -1
- package/.next/server/app/api/server/generate/route.js +2 -2
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chat.html +1 -1
- package/.next/server/app/chat.rsc +17 -17
- package/.next/server/app/chat.segments/_full.segment.rsc +17 -17
- package/.next/server/app/chat.segments/_head.segment.rsc +4 -4
- package/.next/server/app/chat.segments/_index.segment.rsc +11 -11
- package/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/chat.segments/chat.segment.rsc +3 -3
- package/.next/server/app/data/page_client-reference-manifest.js +1 -1
- package/.next/server/app/data.html +1 -1
- package/.next/server/app/data.rsc +17 -17
- package/.next/server/app/data.segments/_full.segment.rsc +17 -17
- package/.next/server/app/data.segments/_head.segment.rsc +4 -4
- package/.next/server/app/data.segments/_index.segment.rsc +11 -11
- package/.next/server/app/data.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/data.segments/data.segment.rsc +3 -3
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +16 -16
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +16 -16
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +11 -11
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +18 -18
- package/.next/server/app/settings.segments/_full.segment.rsc +18 -18
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +11 -11
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/chunks/[root-of-the-server]__05707i3._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0vmcld0._.js +3 -0
- package/.next/{standalone/apps/web/.next/server/chunks/[root-of-the-server]__08f60c7._.js → server/chunks/[root-of-the-server]__1e8p5bd._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__1ks-3_h._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1lhfkyh._.js +1 -1
- package/.next/server/chunks/packages_marketplace_src_125_g2p._.js +1 -1
- package/.next/server/chunks/packages_scraper_src_0kkcv_v._.js +1 -1
- package/.next/server/chunks/packages_tools_video-audio_dist_ffmpeg-spawn_0by2bau.js +3 -0
- package/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
- package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
- package/.next/standalone/apps/web/.next/required-server-files.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +16 -16
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_full.segment.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/api/chat/route.js +9 -9
- package/.next/standalone/apps/web/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/edit/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/export/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/extract-text/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/parse/route.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/restore/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/document/sign/route.js +3 -3
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/[toolId]/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/media/process/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/media/route.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/parse-file/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/api/server/download/route.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/api/server/generate/route.js +2 -2
- package/.next/standalone/apps/web/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_full.segment.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/chat.segments/chat.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/data/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/data.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/data.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/data.segments/_full.segment.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/data.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/data.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/data.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/data.segments/data.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.rsc +16 -16
- package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +16 -16
- package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.rsc +18 -18
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +18 -18
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +11 -11
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__05707i3._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0vmcld0._.js +3 -0
- package/.next/{server/chunks/[root-of-the-server]__08f60c7._.js → standalone/apps/web/.next/server/chunks/[root-of-the-server]__1e8p5bd._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__1ks-3_h._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__1lhfkyh._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/packages_marketplace_src_125_g2p._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/packages_scraper_src_0kkcv_v._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/packages_tools_video-audio_dist_ffmpeg-spawn_0by2bau.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
- package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
- package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/{041vy184s-7sh.js → 2azppfcsqga3r.js} +1 -1
- package/.next/standalone/apps/web/CHANGELOG.md +18 -0
- package/.next/standalone/apps/web/components/update-banner.tsx +2 -2
- package/.next/standalone/apps/web/package.json +1 -1
- package/.next/standalone/apps/web/server.js +1 -1
- package/.next/standalone/packages/tools/video-audio/CHANGELOG.md +6 -0
- package/.next/standalone/packages/tools/video-audio/dist/audio-processor.js +30 -32
- package/.next/standalone/packages/tools/video-audio/dist/ffmpeg-spawn.js +127 -0
- package/.next/standalone/packages/tools/video-audio/dist/video-processor.js +95 -113
- package/.next/standalone/packages/tools/video-audio/package.json +2 -7
- package/.next/standalone/packages/tools/video-audio/src/audio-processor.ts +30 -31
- package/.next/standalone/packages/tools/video-audio/src/ffmpeg-spawn.ts +176 -0
- package/.next/standalone/packages/tools/video-audio/src/video-processor.ts +88 -116
- package/.next/static/chunks/{041vy184s-7sh.js → 2azppfcsqga3r.js} +1 -1
- package/CHANGELOG.md +18 -0
- package/LICENSE +176 -0
- package/components/update-banner.tsx +2 -2
- package/package.json +6 -6
- package/.next/server/chunks/[externals]__1_tvo45._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__010rwkn._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0xbvdcw._.js +0 -3
- package/.next/server/chunks/node_modules__pnpm_0ddqx71._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/[externals]__1_tvo45._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__010rwkn._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0xbvdcw._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/node_modules__pnpm_0ddqx71._.js +0 -3
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/capabilities.js +0 -665
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/ffprobe.js +0 -261
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/fluent-ffmpeg.js +0 -226
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/audio.js +0 -178
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/custom.js +0 -212
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/inputs.js +0 -178
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/misc.js +0 -41
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/output.js +0 -162
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/video.js +0 -184
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/videosize.js +0 -291
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/divx.js +0 -14
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/flashvideo.js +0 -16
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/podcast.js +0 -16
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/processor.js +0 -662
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/recipes.js +0 -456
- package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/utils.js +0 -455
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/CHANGELOG.md +0 -152
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/LICENSE +0 -15
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/README.md +0 -51
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/bin/which +0 -52
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/package.json +0 -30
- package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/which.js +0 -135
- /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_buildManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_ssgManifest.js +0 -0
- /package/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_buildManifest.js +0 -0
- /package/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_ssgManifest.js +0 -0
|
@@ -1,456 +0,0 @@
|
|
|
1
|
-
/*jshint node:true*/
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
var fs = require('fs');
|
|
5
|
-
var path = require('path');
|
|
6
|
-
var PassThrough = require('stream').PassThrough;
|
|
7
|
-
var async = require('async');
|
|
8
|
-
var utils = require('./utils');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/*
|
|
12
|
-
* Useful recipes for commands
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
module.exports = function recipes(proto) {
|
|
16
|
-
/**
|
|
17
|
-
* Execute ffmpeg command and save output to a file
|
|
18
|
-
*
|
|
19
|
-
* @method FfmpegCommand#save
|
|
20
|
-
* @category Processing
|
|
21
|
-
* @aliases saveToFile
|
|
22
|
-
*
|
|
23
|
-
* @param {String} output file path
|
|
24
|
-
* @return FfmpegCommand
|
|
25
|
-
*/
|
|
26
|
-
proto.saveToFile =
|
|
27
|
-
proto.save = function(output) {
|
|
28
|
-
this.output(output).run();
|
|
29
|
-
return this;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Execute ffmpeg command and save output to a stream
|
|
35
|
-
*
|
|
36
|
-
* If 'stream' is not specified, a PassThrough stream is created and returned.
|
|
37
|
-
* 'options' will be used when piping ffmpeg output to the output stream
|
|
38
|
-
* (@see http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options)
|
|
39
|
-
*
|
|
40
|
-
* @method FfmpegCommand#pipe
|
|
41
|
-
* @category Processing
|
|
42
|
-
* @aliases stream,writeToStream
|
|
43
|
-
*
|
|
44
|
-
* @param {stream.Writable} [stream] output stream
|
|
45
|
-
* @param {Object} [options={}] pipe options
|
|
46
|
-
* @return Output stream
|
|
47
|
-
*/
|
|
48
|
-
proto.writeToStream =
|
|
49
|
-
proto.pipe =
|
|
50
|
-
proto.stream = function(stream, options) {
|
|
51
|
-
if (stream && !('writable' in stream)) {
|
|
52
|
-
options = stream;
|
|
53
|
-
stream = undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (!stream) {
|
|
57
|
-
if (process.version.match(/v0\.8\./)) {
|
|
58
|
-
throw new Error('PassThrough stream is not supported on node v0.8');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
stream = new PassThrough();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
this.output(stream, options).run();
|
|
65
|
-
return stream;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Generate images from a video
|
|
71
|
-
*
|
|
72
|
-
* Note: this method makes the command emit a 'filenames' event with an array of
|
|
73
|
-
* the generated image filenames.
|
|
74
|
-
*
|
|
75
|
-
* @method FfmpegCommand#screenshots
|
|
76
|
-
* @category Processing
|
|
77
|
-
* @aliases takeScreenshots,thumbnail,thumbnails,screenshot
|
|
78
|
-
*
|
|
79
|
-
* @param {Number|Object} [config=1] screenshot count or configuration object with
|
|
80
|
-
* the following keys:
|
|
81
|
-
* @param {Number} [config.count] number of screenshots to take; using this option
|
|
82
|
-
* takes screenshots at regular intervals (eg. count=4 would take screens at 20%, 40%,
|
|
83
|
-
* 60% and 80% of the video length).
|
|
84
|
-
* @param {String} [config.folder='.'] output folder
|
|
85
|
-
* @param {String} [config.filename='tn.png'] output filename pattern, may contain the following
|
|
86
|
-
* tokens:
|
|
87
|
-
* - '%s': offset in seconds
|
|
88
|
-
* - '%w': screenshot width
|
|
89
|
-
* - '%h': screenshot height
|
|
90
|
-
* - '%r': screenshot resolution (same as '%wx%h')
|
|
91
|
-
* - '%f': input filename
|
|
92
|
-
* - '%b': input basename (filename w/o extension)
|
|
93
|
-
* - '%i': index of screenshot in timemark array (can be zero-padded by using it like `%000i`)
|
|
94
|
-
* @param {Number[]|String[]} [config.timemarks] array of timemarks to take screenshots
|
|
95
|
-
* at; each timemark may be a number of seconds, a '[[hh:]mm:]ss[.xxx]' string or a
|
|
96
|
-
* 'XX%' string. Overrides 'count' if present.
|
|
97
|
-
* @param {Number[]|String[]} [config.timestamps] alias for 'timemarks'
|
|
98
|
-
* @param {Boolean} [config.fastSeek] use fast seek (less accurate)
|
|
99
|
-
* @param {String} [config.size] screenshot size, with the same syntax as {@link FfmpegCommand#size}
|
|
100
|
-
* @param {String} [folder] output folder (legacy alias for 'config.folder')
|
|
101
|
-
* @return FfmpegCommand
|
|
102
|
-
*/
|
|
103
|
-
proto.takeScreenshots =
|
|
104
|
-
proto.thumbnail =
|
|
105
|
-
proto.thumbnails =
|
|
106
|
-
proto.screenshot =
|
|
107
|
-
proto.screenshots = function(config, folder) {
|
|
108
|
-
var self = this;
|
|
109
|
-
var source = this._currentInput.source;
|
|
110
|
-
config = config || { count: 1 };
|
|
111
|
-
|
|
112
|
-
// Accept a number of screenshots instead of a config object
|
|
113
|
-
if (typeof config === 'number') {
|
|
114
|
-
config = {
|
|
115
|
-
count: config
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Accept a second 'folder' parameter instead of config.folder
|
|
120
|
-
if (!('folder' in config)) {
|
|
121
|
-
config.folder = folder || '.';
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Accept 'timestamps' instead of 'timemarks'
|
|
125
|
-
if ('timestamps' in config) {
|
|
126
|
-
config.timemarks = config.timestamps;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Compute timemarks from count if not present
|
|
130
|
-
if (!('timemarks' in config)) {
|
|
131
|
-
if (!config.count) {
|
|
132
|
-
throw new Error('Cannot take screenshots: neither a count nor a timemark list are specified');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
var interval = 100 / (1 + config.count);
|
|
136
|
-
config.timemarks = [];
|
|
137
|
-
for (var i = 0; i < config.count; i++) {
|
|
138
|
-
config.timemarks.push((interval * (i + 1)) + '%');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Parse size option
|
|
143
|
-
if ('size' in config) {
|
|
144
|
-
var fixedSize = config.size.match(/^(\d+)x(\d+)$/);
|
|
145
|
-
var fixedWidth = config.size.match(/^(\d+)x\?$/);
|
|
146
|
-
var fixedHeight = config.size.match(/^\?x(\d+)$/);
|
|
147
|
-
var percentSize = config.size.match(/^(\d+)%$/);
|
|
148
|
-
|
|
149
|
-
if (!fixedSize && !fixedWidth && !fixedHeight && !percentSize) {
|
|
150
|
-
throw new Error('Invalid size parameter: ' + config.size);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Metadata helper
|
|
155
|
-
var metadata;
|
|
156
|
-
function getMetadata(cb) {
|
|
157
|
-
if (metadata) {
|
|
158
|
-
cb(null, metadata);
|
|
159
|
-
} else {
|
|
160
|
-
self.ffprobe(function(err, meta) {
|
|
161
|
-
metadata = meta;
|
|
162
|
-
cb(err, meta);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async.waterfall([
|
|
168
|
-
// Compute percent timemarks if any
|
|
169
|
-
function computeTimemarks(next) {
|
|
170
|
-
if (config.timemarks.some(function(t) { return ('' + t).match(/^[\d.]+%$/); })) {
|
|
171
|
-
if (typeof source !== 'string') {
|
|
172
|
-
return next(new Error('Cannot compute screenshot timemarks with an input stream, please specify fixed timemarks'));
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getMetadata(function(err, meta) {
|
|
176
|
-
if (err) {
|
|
177
|
-
next(err);
|
|
178
|
-
} else {
|
|
179
|
-
// Select video stream with the highest resolution
|
|
180
|
-
var vstream = meta.streams.reduce(function(biggest, stream) {
|
|
181
|
-
if (stream.codec_type === 'video' && stream.width * stream.height > biggest.width * biggest.height) {
|
|
182
|
-
return stream;
|
|
183
|
-
} else {
|
|
184
|
-
return biggest;
|
|
185
|
-
}
|
|
186
|
-
}, { width: 0, height: 0 });
|
|
187
|
-
|
|
188
|
-
if (vstream.width === 0) {
|
|
189
|
-
return next(new Error('No video stream in input, cannot take screenshots'));
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
var duration = Number(vstream.duration);
|
|
193
|
-
if (isNaN(duration)) {
|
|
194
|
-
duration = Number(meta.format.duration);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (isNaN(duration)) {
|
|
198
|
-
return next(new Error('Could not get input duration, please specify fixed timemarks'));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
config.timemarks = config.timemarks.map(function(mark) {
|
|
202
|
-
if (('' + mark).match(/^([\d.]+)%$/)) {
|
|
203
|
-
return duration * parseFloat(mark) / 100;
|
|
204
|
-
} else {
|
|
205
|
-
return mark;
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
next();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
} else {
|
|
213
|
-
next();
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
// Turn all timemarks into numbers and sort them
|
|
218
|
-
function normalizeTimemarks(next) {
|
|
219
|
-
config.timemarks = config.timemarks.map(function(mark) {
|
|
220
|
-
return utils.timemarkToSeconds(mark);
|
|
221
|
-
}).sort(function(a, b) { return a - b; });
|
|
222
|
-
|
|
223
|
-
next();
|
|
224
|
-
},
|
|
225
|
-
|
|
226
|
-
// Add '_%i' to pattern when requesting multiple screenshots and no variable token is present
|
|
227
|
-
function fixPattern(next) {
|
|
228
|
-
var pattern = config.filename || 'tn.png';
|
|
229
|
-
|
|
230
|
-
if (pattern.indexOf('.') === -1) {
|
|
231
|
-
pattern += '.png';
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (config.timemarks.length > 1 && !pattern.match(/%(s|0*i)/)) {
|
|
235
|
-
var ext = path.extname(pattern);
|
|
236
|
-
pattern = path.join(path.dirname(pattern), path.basename(pattern, ext) + '_%i' + ext);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
next(null, pattern);
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
// Replace filename tokens (%f, %b) in pattern
|
|
243
|
-
function replaceFilenameTokens(pattern, next) {
|
|
244
|
-
if (pattern.match(/%[bf]/)) {
|
|
245
|
-
if (typeof source !== 'string') {
|
|
246
|
-
return next(new Error('Cannot replace %f or %b when using an input stream'));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
pattern = pattern
|
|
250
|
-
.replace(/%f/g, path.basename(source))
|
|
251
|
-
.replace(/%b/g, path.basename(source, path.extname(source)));
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
next(null, pattern);
|
|
255
|
-
},
|
|
256
|
-
|
|
257
|
-
// Compute size if needed
|
|
258
|
-
function getSize(pattern, next) {
|
|
259
|
-
if (pattern.match(/%[whr]/)) {
|
|
260
|
-
if (fixedSize) {
|
|
261
|
-
return next(null, pattern, fixedSize[1], fixedSize[2]);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
getMetadata(function(err, meta) {
|
|
265
|
-
if (err) {
|
|
266
|
-
return next(new Error('Could not determine video resolution to replace %w, %h or %r'));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
var vstream = meta.streams.reduce(function(biggest, stream) {
|
|
270
|
-
if (stream.codec_type === 'video' && stream.width * stream.height > biggest.width * biggest.height) {
|
|
271
|
-
return stream;
|
|
272
|
-
} else {
|
|
273
|
-
return biggest;
|
|
274
|
-
}
|
|
275
|
-
}, { width: 0, height: 0 });
|
|
276
|
-
|
|
277
|
-
if (vstream.width === 0) {
|
|
278
|
-
return next(new Error('No video stream in input, cannot replace %w, %h or %r'));
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
var width = vstream.width;
|
|
282
|
-
var height = vstream.height;
|
|
283
|
-
|
|
284
|
-
if (fixedWidth) {
|
|
285
|
-
height = height * Number(fixedWidth[1]) / width;
|
|
286
|
-
width = Number(fixedWidth[1]);
|
|
287
|
-
} else if (fixedHeight) {
|
|
288
|
-
width = width * Number(fixedHeight[1]) / height;
|
|
289
|
-
height = Number(fixedHeight[1]);
|
|
290
|
-
} else if (percentSize) {
|
|
291
|
-
width = width * Number(percentSize[1]) / 100;
|
|
292
|
-
height = height * Number(percentSize[1]) / 100;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
next(null, pattern, Math.round(width / 2) * 2, Math.round(height / 2) * 2);
|
|
296
|
-
});
|
|
297
|
-
} else {
|
|
298
|
-
next(null, pattern, -1, -1);
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
|
|
302
|
-
// Replace size tokens (%w, %h, %r) in pattern
|
|
303
|
-
function replaceSizeTokens(pattern, width, height, next) {
|
|
304
|
-
pattern = pattern
|
|
305
|
-
.replace(/%r/g, '%wx%h')
|
|
306
|
-
.replace(/%w/g, width)
|
|
307
|
-
.replace(/%h/g, height);
|
|
308
|
-
|
|
309
|
-
next(null, pattern);
|
|
310
|
-
},
|
|
311
|
-
|
|
312
|
-
// Replace variable tokens in pattern (%s, %i) and generate filename list
|
|
313
|
-
function replaceVariableTokens(pattern, next) {
|
|
314
|
-
var filenames = config.timemarks.map(function(t, i) {
|
|
315
|
-
return pattern
|
|
316
|
-
.replace(/%s/g, utils.timemarkToSeconds(t))
|
|
317
|
-
.replace(/%(0*)i/g, function(match, padding) {
|
|
318
|
-
var idx = '' + (i + 1);
|
|
319
|
-
return padding.substr(0, Math.max(0, padding.length + 1 - idx.length)) + idx;
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
self.emit('filenames', filenames);
|
|
324
|
-
next(null, filenames);
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
// Create output directory
|
|
328
|
-
function createDirectory(filenames, next) {
|
|
329
|
-
fs.exists(config.folder, function(exists) {
|
|
330
|
-
if (!exists) {
|
|
331
|
-
fs.mkdir(config.folder, function(err) {
|
|
332
|
-
if (err) {
|
|
333
|
-
next(err);
|
|
334
|
-
} else {
|
|
335
|
-
next(null, filenames);
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
} else {
|
|
339
|
-
next(null, filenames);
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
], function runCommand(err, filenames) {
|
|
344
|
-
if (err) {
|
|
345
|
-
return self.emit('error', err);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
var count = config.timemarks.length;
|
|
349
|
-
var split;
|
|
350
|
-
var filters = [split = {
|
|
351
|
-
filter: 'split',
|
|
352
|
-
options: count,
|
|
353
|
-
outputs: []
|
|
354
|
-
}];
|
|
355
|
-
|
|
356
|
-
if ('size' in config) {
|
|
357
|
-
// Set size to generate size filters
|
|
358
|
-
self.size(config.size);
|
|
359
|
-
|
|
360
|
-
// Get size filters and chain them with 'sizeN' stream names
|
|
361
|
-
var sizeFilters = self._currentOutput.sizeFilters.get().map(function(f, i) {
|
|
362
|
-
if (i > 0) {
|
|
363
|
-
f.inputs = 'size' + (i - 1);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
f.outputs = 'size' + i;
|
|
367
|
-
|
|
368
|
-
return f;
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// Input last size filter output into split filter
|
|
372
|
-
split.inputs = 'size' + (sizeFilters.length - 1);
|
|
373
|
-
|
|
374
|
-
// Add size filters in front of split filter
|
|
375
|
-
filters = sizeFilters.concat(filters);
|
|
376
|
-
|
|
377
|
-
// Remove size filters
|
|
378
|
-
self._currentOutput.sizeFilters.clear();
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
var first = 0;
|
|
382
|
-
for (var i = 0; i < count; i++) {
|
|
383
|
-
var stream = 'screen' + i;
|
|
384
|
-
split.outputs.push(stream);
|
|
385
|
-
|
|
386
|
-
if (i === 0) {
|
|
387
|
-
first = config.timemarks[i];
|
|
388
|
-
self.seekInput(first);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
self.output(path.join(config.folder, filenames[i]))
|
|
392
|
-
.frames(1)
|
|
393
|
-
.map(stream);
|
|
394
|
-
|
|
395
|
-
if (i > 0) {
|
|
396
|
-
self.seek(config.timemarks[i] - first);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
self.complexFilter(filters);
|
|
401
|
-
self.run();
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
return this;
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Merge (concatenate) inputs to a single file
|
|
410
|
-
*
|
|
411
|
-
* @method FfmpegCommand#concat
|
|
412
|
-
* @category Processing
|
|
413
|
-
* @aliases concatenate,mergeToFile
|
|
414
|
-
*
|
|
415
|
-
* @param {String|Writable} target output file or writable stream
|
|
416
|
-
* @param {Object} [options] pipe options (only used when outputting to a writable stream)
|
|
417
|
-
* @return FfmpegCommand
|
|
418
|
-
*/
|
|
419
|
-
proto.mergeToFile =
|
|
420
|
-
proto.concatenate =
|
|
421
|
-
proto.concat = function(target, options) {
|
|
422
|
-
// Find out which streams are present in the first non-stream input
|
|
423
|
-
var fileInput = this._inputs.filter(function(input) {
|
|
424
|
-
return !input.isStream;
|
|
425
|
-
})[0];
|
|
426
|
-
|
|
427
|
-
var self = this;
|
|
428
|
-
this.ffprobe(this._inputs.indexOf(fileInput), function(err, data) {
|
|
429
|
-
if (err) {
|
|
430
|
-
return self.emit('error', err);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
var hasAudioStreams = data.streams.some(function(stream) {
|
|
434
|
-
return stream.codec_type === 'audio';
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
var hasVideoStreams = data.streams.some(function(stream) {
|
|
438
|
-
return stream.codec_type === 'video';
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
// Setup concat filter and start processing
|
|
442
|
-
self.output(target, options)
|
|
443
|
-
.complexFilter({
|
|
444
|
-
filter: 'concat',
|
|
445
|
-
options: {
|
|
446
|
-
n: self._inputs.length,
|
|
447
|
-
v: hasVideoStreams ? 1 : 0,
|
|
448
|
-
a: hasAudioStreams ? 1 : 0
|
|
449
|
-
}
|
|
450
|
-
})
|
|
451
|
-
.run();
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
return this;
|
|
455
|
-
};
|
|
456
|
-
};
|