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.
Files changed (241) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/diagnostics/route-bundle-stats.json +12 -12
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/required-server-files.js +1 -1
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/_not-found.html +1 -1
  16. package/.next/server/app/_not-found.rsc +16 -16
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
  18. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  19. package/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  21. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
  24. package/.next/server/app/analytics.html +1 -1
  25. package/.next/server/app/analytics.rsc +17 -17
  26. package/.next/server/app/analytics.segments/_full.segment.rsc +17 -17
  27. package/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
  28. package/.next/server/app/analytics.segments/_index.segment.rsc +11 -11
  29. package/.next/server/app/analytics.segments/_tree.segment.rsc +1 -1
  30. package/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
  31. package/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
  32. package/.next/server/app/api/chat/route.js +9 -9
  33. package/.next/server/app/api/chat/route.js.nft.json +1 -1
  34. package/.next/server/app/api/deploy/ssh/route.js +2 -2
  35. package/.next/server/app/api/deploy/ssh/route.js.nft.json +1 -1
  36. package/.next/server/app/api/doc-editor/edit/route.js +2 -2
  37. package/.next/server/app/api/doc-editor/export/route.js +2 -2
  38. package/.next/server/app/api/doc-editor/extract-text/route.js +2 -2
  39. package/.next/server/app/api/doc-editor/parse/route.js +1 -1
  40. package/.next/server/app/api/doc-editor/restore/route.js +2 -2
  41. package/.next/server/app/api/document/sign/route.js +3 -3
  42. package/.next/server/app/api/marketplace/[toolId]/route.js.nft.json +1 -1
  43. package/.next/server/app/api/marketplace/route.js.nft.json +1 -1
  44. package/.next/server/app/api/media/process/route.js.nft.json +1 -1
  45. package/.next/server/app/api/media/route.js.nft.json +1 -1
  46. package/.next/server/app/api/parse-file/route.js +2 -2
  47. package/.next/server/app/api/server/download/route.js +1 -1
  48. package/.next/server/app/api/server/generate/route.js +2 -2
  49. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  50. package/.next/server/app/chat.html +1 -1
  51. package/.next/server/app/chat.rsc +17 -17
  52. package/.next/server/app/chat.segments/_full.segment.rsc +17 -17
  53. package/.next/server/app/chat.segments/_head.segment.rsc +4 -4
  54. package/.next/server/app/chat.segments/_index.segment.rsc +11 -11
  55. package/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
  56. package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
  57. package/.next/server/app/chat.segments/chat.segment.rsc +3 -3
  58. package/.next/server/app/data/page_client-reference-manifest.js +1 -1
  59. package/.next/server/app/data.html +1 -1
  60. package/.next/server/app/data.rsc +17 -17
  61. package/.next/server/app/data.segments/_full.segment.rsc +17 -17
  62. package/.next/server/app/data.segments/_head.segment.rsc +4 -4
  63. package/.next/server/app/data.segments/_index.segment.rsc +11 -11
  64. package/.next/server/app/data.segments/_tree.segment.rsc +1 -1
  65. package/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
  66. package/.next/server/app/data.segments/data.segment.rsc +3 -3
  67. package/.next/server/app/index.html +1 -1
  68. package/.next/server/app/index.rsc +16 -16
  69. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  70. package/.next/server/app/index.segments/_full.segment.rsc +16 -16
  71. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  72. package/.next/server/app/index.segments/_index.segment.rsc +11 -11
  73. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  74. package/.next/server/app/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  76. package/.next/server/app/settings.html +1 -1
  77. package/.next/server/app/settings.rsc +18 -18
  78. package/.next/server/app/settings.segments/_full.segment.rsc +18 -18
  79. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  80. package/.next/server/app/settings.segments/_index.segment.rsc +11 -11
  81. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  82. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  83. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  84. package/.next/server/chunks/[root-of-the-server]__05707i3._.js +1 -1
  85. package/.next/server/chunks/[root-of-the-server]__0vmcld0._.js +3 -0
  86. package/.next/{standalone/apps/web/.next/server/chunks/[root-of-the-server]__08f60c7._.js → server/chunks/[root-of-the-server]__1e8p5bd._.js} +2 -2
  87. package/.next/server/chunks/[root-of-the-server]__1ks-3_h._.js +3 -0
  88. package/.next/server/chunks/[root-of-the-server]__1lhfkyh._.js +1 -1
  89. package/.next/server/chunks/packages_marketplace_src_125_g2p._.js +1 -1
  90. package/.next/server/chunks/packages_scraper_src_0kkcv_v._.js +1 -1
  91. package/.next/server/chunks/packages_tools_video-audio_dist_ffmpeg-spawn_0by2bau.js +3 -0
  92. package/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
  93. package/.next/server/middleware-build-manifest.js +3 -3
  94. package/.next/server/pages/404.html +1 -1
  95. package/.next/server/pages/500.html +1 -1
  96. package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
  97. package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
  98. package/.next/standalone/apps/web/.next/required-server-files.json +1 -1
  99. package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
  100. package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
  101. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  102. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  103. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  104. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  105. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  106. package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  107. package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
  108. package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +16 -16
  109. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
  110. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  111. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  112. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  113. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  114. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  115. package/.next/standalone/apps/web/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
  116. package/.next/standalone/apps/web/.next/server/app/analytics.html +1 -1
  117. package/.next/standalone/apps/web/.next/server/app/analytics.rsc +17 -17
  118. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_full.segment.rsc +17 -17
  119. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
  120. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_index.segment.rsc +11 -11
  121. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_tree.segment.rsc +1 -1
  122. package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
  123. package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
  124. package/.next/standalone/apps/web/.next/server/app/api/chat/route.js +9 -9
  125. package/.next/standalone/apps/web/.next/server/app/api/chat/route.js.nft.json +1 -1
  126. package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js +2 -2
  127. package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js.nft.json +1 -1
  128. package/.next/standalone/apps/web/.next/server/app/api/doc-editor/edit/route.js +2 -2
  129. package/.next/standalone/apps/web/.next/server/app/api/doc-editor/export/route.js +2 -2
  130. package/.next/standalone/apps/web/.next/server/app/api/doc-editor/extract-text/route.js +2 -2
  131. package/.next/standalone/apps/web/.next/server/app/api/doc-editor/parse/route.js +1 -1
  132. package/.next/standalone/apps/web/.next/server/app/api/doc-editor/restore/route.js +2 -2
  133. package/.next/standalone/apps/web/.next/server/app/api/document/sign/route.js +3 -3
  134. package/.next/standalone/apps/web/.next/server/app/api/marketplace/[toolId]/route.js.nft.json +1 -1
  135. package/.next/standalone/apps/web/.next/server/app/api/marketplace/route.js.nft.json +1 -1
  136. package/.next/standalone/apps/web/.next/server/app/api/media/process/route.js.nft.json +1 -1
  137. package/.next/standalone/apps/web/.next/server/app/api/media/route.js.nft.json +1 -1
  138. package/.next/standalone/apps/web/.next/server/app/api/parse-file/route.js +2 -2
  139. package/.next/standalone/apps/web/.next/server/app/api/server/download/route.js +1 -1
  140. package/.next/standalone/apps/web/.next/server/app/api/server/generate/route.js +2 -2
  141. package/.next/standalone/apps/web/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  142. package/.next/standalone/apps/web/.next/server/app/chat.html +1 -1
  143. package/.next/standalone/apps/web/.next/server/app/chat.rsc +17 -17
  144. package/.next/standalone/apps/web/.next/server/app/chat.segments/_full.segment.rsc +17 -17
  145. package/.next/standalone/apps/web/.next/server/app/chat.segments/_head.segment.rsc +4 -4
  146. package/.next/standalone/apps/web/.next/server/app/chat.segments/_index.segment.rsc +11 -11
  147. package/.next/standalone/apps/web/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
  148. package/.next/standalone/apps/web/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
  149. package/.next/standalone/apps/web/.next/server/app/chat.segments/chat.segment.rsc +3 -3
  150. package/.next/standalone/apps/web/.next/server/app/data/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/apps/web/.next/server/app/data.html +1 -1
  152. package/.next/standalone/apps/web/.next/server/app/data.rsc +17 -17
  153. package/.next/standalone/apps/web/.next/server/app/data.segments/_full.segment.rsc +17 -17
  154. package/.next/standalone/apps/web/.next/server/app/data.segments/_head.segment.rsc +4 -4
  155. package/.next/standalone/apps/web/.next/server/app/data.segments/_index.segment.rsc +11 -11
  156. package/.next/standalone/apps/web/.next/server/app/data.segments/_tree.segment.rsc +1 -1
  157. package/.next/standalone/apps/web/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
  158. package/.next/standalone/apps/web/.next/server/app/data.segments/data.segment.rsc +3 -3
  159. package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
  160. package/.next/standalone/apps/web/.next/server/app/index.rsc +16 -16
  161. package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  162. package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +16 -16
  163. package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +4 -4
  164. package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +11 -11
  165. package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  166. package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  167. package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  168. package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
  169. package/.next/standalone/apps/web/.next/server/app/settings.rsc +18 -18
  170. package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +18 -18
  171. package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  172. package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +11 -11
  173. package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  174. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  175. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  176. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__05707i3._.js +1 -1
  177. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0vmcld0._.js +3 -0
  178. package/.next/{server/chunks/[root-of-the-server]__08f60c7._.js → standalone/apps/web/.next/server/chunks/[root-of-the-server]__1e8p5bd._.js} +2 -2
  179. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__1ks-3_h._.js +3 -0
  180. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__1lhfkyh._.js +1 -1
  181. package/.next/standalone/apps/web/.next/server/chunks/packages_marketplace_src_125_g2p._.js +1 -1
  182. package/.next/standalone/apps/web/.next/server/chunks/packages_scraper_src_0kkcv_v._.js +1 -1
  183. package/.next/standalone/apps/web/.next/server/chunks/packages_tools_video-audio_dist_ffmpeg-spawn_0by2bau.js +3 -0
  184. package/.next/standalone/apps/web/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
  185. package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
  186. package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
  187. package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  188. package/.next/standalone/apps/web/.next/static/chunks/{041vy184s-7sh.js → 2azppfcsqga3r.js} +1 -1
  189. package/.next/standalone/apps/web/CHANGELOG.md +18 -0
  190. package/.next/standalone/apps/web/components/update-banner.tsx +2 -2
  191. package/.next/standalone/apps/web/package.json +1 -1
  192. package/.next/standalone/apps/web/server.js +1 -1
  193. package/.next/standalone/packages/tools/video-audio/CHANGELOG.md +6 -0
  194. package/.next/standalone/packages/tools/video-audio/dist/audio-processor.js +30 -32
  195. package/.next/standalone/packages/tools/video-audio/dist/ffmpeg-spawn.js +127 -0
  196. package/.next/standalone/packages/tools/video-audio/dist/video-processor.js +95 -113
  197. package/.next/standalone/packages/tools/video-audio/package.json +2 -7
  198. package/.next/standalone/packages/tools/video-audio/src/audio-processor.ts +30 -31
  199. package/.next/standalone/packages/tools/video-audio/src/ffmpeg-spawn.ts +176 -0
  200. package/.next/standalone/packages/tools/video-audio/src/video-processor.ts +88 -116
  201. package/.next/static/chunks/{041vy184s-7sh.js → 2azppfcsqga3r.js} +1 -1
  202. package/CHANGELOG.md +18 -0
  203. package/LICENSE +176 -0
  204. package/components/update-banner.tsx +2 -2
  205. package/package.json +6 -6
  206. package/.next/server/chunks/[externals]__1_tvo45._.js +0 -3
  207. package/.next/server/chunks/[root-of-the-server]__010rwkn._.js +0 -3
  208. package/.next/server/chunks/[root-of-the-server]__0xbvdcw._.js +0 -3
  209. package/.next/server/chunks/node_modules__pnpm_0ddqx71._.js +0 -3
  210. package/.next/standalone/apps/web/.next/server/chunks/[externals]__1_tvo45._.js +0 -3
  211. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__010rwkn._.js +0 -3
  212. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0xbvdcw._.js +0 -3
  213. package/.next/standalone/apps/web/.next/server/chunks/node_modules__pnpm_0ddqx71._.js +0 -3
  214. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/capabilities.js +0 -665
  215. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/ffprobe.js +0 -261
  216. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/fluent-ffmpeg.js +0 -226
  217. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/audio.js +0 -178
  218. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/custom.js +0 -212
  219. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/inputs.js +0 -178
  220. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/misc.js +0 -41
  221. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/output.js +0 -162
  222. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/video.js +0 -184
  223. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/options/videosize.js +0 -291
  224. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/divx.js +0 -14
  225. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/flashvideo.js +0 -16
  226. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/presets/podcast.js +0 -16
  227. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/processor.js +0 -662
  228. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/recipes.js +0 -456
  229. package/.next/standalone/node_modules/.pnpm/fluent-ffmpeg@2.1.3/node_modules/fluent-ffmpeg/lib/utils.js +0 -455
  230. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/CHANGELOG.md +0 -152
  231. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/LICENSE +0 -15
  232. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/README.md +0 -51
  233. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/bin/which +0 -52
  234. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/package.json +0 -30
  235. package/.next/standalone/node_modules/.pnpm/which@1.3.1/node_modules/which/which.js +0 -135
  236. /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_buildManifest.js +0 -0
  237. /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_clientMiddlewareManifest.js +0 -0
  238. /package/.next/standalone/apps/web/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_ssgManifest.js +0 -0
  239. /package/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_buildManifest.js +0 -0
  240. /package/.next/static/{IHAOZOY0iJJ_cMmT7-lqT → PM7-3u8cSkShjD80zaJ4l}/_clientMiddlewareManifest.js +0 -0
  241. /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
- };