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,662 +0,0 @@
1
- /*jshint node:true*/
2
- 'use strict';
3
-
4
- var spawn = require('child_process').spawn;
5
- var path = require('path');
6
- var fs = require('fs');
7
- var async = require('async');
8
- var utils = require('./utils');
9
-
10
- /*
11
- *! Processor methods
12
- */
13
-
14
-
15
- /**
16
- * Run ffprobe asynchronously and store data in command
17
- *
18
- * @param {FfmpegCommand} command
19
- * @private
20
- */
21
- function runFfprobe(command) {
22
- const inputProbeIndex = 0;
23
- if (command._inputs[inputProbeIndex].isStream) {
24
- // Don't probe input streams as this will consume them
25
- return;
26
- }
27
- command.ffprobe(inputProbeIndex, function(err, data) {
28
- command._ffprobeData = data;
29
- });
30
- }
31
-
32
-
33
- module.exports = function(proto) {
34
- /**
35
- * Emitted just after ffmpeg has been spawned.
36
- *
37
- * @event FfmpegCommand#start
38
- * @param {String} command ffmpeg command line
39
- */
40
-
41
- /**
42
- * Emitted when ffmpeg reports progress information
43
- *
44
- * @event FfmpegCommand#progress
45
- * @param {Object} progress progress object
46
- * @param {Number} progress.frames number of frames transcoded
47
- * @param {Number} progress.currentFps current processing speed in frames per second
48
- * @param {Number} progress.currentKbps current output generation speed in kilobytes per second
49
- * @param {Number} progress.targetSize current output file size
50
- * @param {String} progress.timemark current video timemark
51
- * @param {Number} [progress.percent] processing progress (may not be available depending on input)
52
- */
53
-
54
- /**
55
- * Emitted when ffmpeg outputs to stderr
56
- *
57
- * @event FfmpegCommand#stderr
58
- * @param {String} line stderr output line
59
- */
60
-
61
- /**
62
- * Emitted when ffmpeg reports input codec data
63
- *
64
- * @event FfmpegCommand#codecData
65
- * @param {Object} codecData codec data object
66
- * @param {String} codecData.format input format name
67
- * @param {String} codecData.audio input audio codec name
68
- * @param {String} codecData.audio_details input audio codec parameters
69
- * @param {String} codecData.video input video codec name
70
- * @param {String} codecData.video_details input video codec parameters
71
- */
72
-
73
- /**
74
- * Emitted when an error happens when preparing or running a command
75
- *
76
- * @event FfmpegCommand#error
77
- * @param {Error} error error object, with optional properties 'inputStreamError' / 'outputStreamError' for errors on their respective streams
78
- * @param {String|null} stdout ffmpeg stdout, unless outputting to a stream
79
- * @param {String|null} stderr ffmpeg stderr
80
- */
81
-
82
- /**
83
- * Emitted when a command finishes processing
84
- *
85
- * @event FfmpegCommand#end
86
- * @param {Array|String|null} [filenames|stdout] generated filenames when taking screenshots, ffmpeg stdout when not outputting to a stream, null otherwise
87
- * @param {String|null} stderr ffmpeg stderr
88
- */
89
-
90
-
91
- /**
92
- * Spawn an ffmpeg process
93
- *
94
- * The 'options' argument may contain the following keys:
95
- * - 'niceness': specify process niceness, ignored on Windows (default: 0)
96
- * - `cwd`: change working directory
97
- * - 'captureStdout': capture stdout and pass it to 'endCB' as its 2nd argument (default: false)
98
- * - 'stdoutLines': override command limit (default: use command limit)
99
- *
100
- * The 'processCB' callback, if present, is called as soon as the process is created and
101
- * receives a nodejs ChildProcess object. It may not be called at all if an error happens
102
- * before spawning the process.
103
- *
104
- * The 'endCB' callback is called either when an error occurs or when the ffmpeg process finishes.
105
- *
106
- * @method FfmpegCommand#_spawnFfmpeg
107
- * @param {Array} args ffmpeg command line argument list
108
- * @param {Object} [options] spawn options (see above)
109
- * @param {Function} [processCB] callback called with process object and stdout/stderr ring buffers when process has been created
110
- * @param {Function} endCB callback called with error (if applicable) and stdout/stderr ring buffers when process finished
111
- * @private
112
- */
113
- proto._spawnFfmpeg = function(args, options, processCB, endCB) {
114
- // Enable omitting options
115
- if (typeof options === 'function') {
116
- endCB = processCB;
117
- processCB = options;
118
- options = {};
119
- }
120
-
121
- // Enable omitting processCB
122
- if (typeof endCB === 'undefined') {
123
- endCB = processCB;
124
- processCB = function() {};
125
- }
126
-
127
- var maxLines = 'stdoutLines' in options ? options.stdoutLines : this.options.stdoutLines;
128
-
129
- // Find ffmpeg
130
- this._getFfmpegPath(function(err, command) {
131
- if (err) {
132
- return endCB(err);
133
- } else if (!command || command.length === 0) {
134
- return endCB(new Error('Cannot find ffmpeg'));
135
- }
136
-
137
- // Apply niceness
138
- if (options.niceness && options.niceness !== 0 && !utils.isWindows) {
139
- args.unshift('-n', options.niceness, command);
140
- command = 'nice';
141
- }
142
-
143
- var stdoutRing = utils.linesRing(maxLines);
144
- var stdoutClosed = false;
145
-
146
- var stderrRing = utils.linesRing(maxLines);
147
- var stderrClosed = false;
148
-
149
- // Spawn process
150
- var ffmpegProc = spawn(command, args, options);
151
-
152
- if (ffmpegProc.stderr) {
153
- ffmpegProc.stderr.setEncoding('utf8');
154
- }
155
-
156
- ffmpegProc.on('error', function(err) {
157
- endCB(err);
158
- });
159
-
160
- // Ensure we wait for captured streams to end before calling endCB
161
- var exitError = null;
162
- function handleExit(err) {
163
- if (err) {
164
- exitError = err;
165
- }
166
-
167
- if (processExited && (stdoutClosed || !options.captureStdout) && stderrClosed) {
168
- endCB(exitError, stdoutRing, stderrRing);
169
- }
170
- }
171
-
172
- // Handle process exit
173
- var processExited = false;
174
- ffmpegProc.on('exit', function(code, signal) {
175
- processExited = true;
176
-
177
- if (signal) {
178
- handleExit(new Error('ffmpeg was killed with signal ' + signal));
179
- } else if (code) {
180
- handleExit(new Error('ffmpeg exited with code ' + code));
181
- } else {
182
- handleExit();
183
- }
184
- });
185
-
186
- // Capture stdout if specified
187
- if (options.captureStdout) {
188
- ffmpegProc.stdout.on('data', function(data) {
189
- stdoutRing.append(data);
190
- });
191
-
192
- ffmpegProc.stdout.on('close', function() {
193
- stdoutRing.close();
194
- stdoutClosed = true;
195
- handleExit();
196
- });
197
- }
198
-
199
- // Capture stderr if specified
200
- ffmpegProc.stderr.on('data', function(data) {
201
- stderrRing.append(data);
202
- });
203
-
204
- ffmpegProc.stderr.on('close', function() {
205
- stderrRing.close();
206
- stderrClosed = true;
207
- handleExit();
208
- });
209
-
210
- // Call process callback
211
- processCB(ffmpegProc, stdoutRing, stderrRing);
212
- });
213
- };
214
-
215
-
216
- /**
217
- * Build the argument list for an ffmpeg command
218
- *
219
- * @method FfmpegCommand#_getArguments
220
- * @return argument list
221
- * @private
222
- */
223
- proto._getArguments = function() {
224
- var complexFilters = this._complexFilters.get();
225
-
226
- var fileOutput = this._outputs.some(function(output) {
227
- return output.isFile;
228
- });
229
-
230
- return [].concat(
231
- // Inputs and input options
232
- this._inputs.reduce(function(args, input) {
233
- var source = (typeof input.source === 'string') ? input.source : 'pipe:0';
234
-
235
- // For each input, add input options, then '-i <source>'
236
- return args.concat(
237
- input.options.get(),
238
- ['-i', source]
239
- );
240
- }, []),
241
-
242
- // Global options
243
- this._global.get(),
244
-
245
- // Overwrite if we have file outputs
246
- fileOutput ? ['-y'] : [],
247
-
248
- // Complex filters
249
- complexFilters,
250
-
251
- // Outputs, filters and output options
252
- this._outputs.reduce(function(args, output) {
253
- var sizeFilters = utils.makeFilterStrings(output.sizeFilters.get());
254
- var audioFilters = output.audioFilters.get();
255
- var videoFilters = output.videoFilters.get().concat(sizeFilters);
256
- var outputArg;
257
-
258
- if (!output.target) {
259
- outputArg = [];
260
- } else if (typeof output.target === 'string') {
261
- outputArg = [output.target];
262
- } else {
263
- outputArg = ['pipe:1'];
264
- }
265
-
266
- return args.concat(
267
- output.audio.get(),
268
- audioFilters.length ? ['-filter:a', audioFilters.join(',')] : [],
269
- output.video.get(),
270
- videoFilters.length ? ['-filter:v', videoFilters.join(',')] : [],
271
- output.options.get(),
272
- outputArg
273
- );
274
- }, [])
275
- );
276
- };
277
-
278
-
279
- /**
280
- * Prepare execution of an ffmpeg command
281
- *
282
- * Checks prerequisites for the execution of the command (codec/format availability, flvtool...),
283
- * then builds the argument list for ffmpeg and pass them to 'callback'.
284
- *
285
- * @method FfmpegCommand#_prepare
286
- * @param {Function} callback callback with signature (err, args)
287
- * @param {Boolean} [readMetadata=false] read metadata before processing
288
- * @private
289
- */
290
- proto._prepare = function(callback, readMetadata) {
291
- var self = this;
292
-
293
- async.waterfall([
294
- // Check codecs and formats
295
- function(cb) {
296
- self._checkCapabilities(cb);
297
- },
298
-
299
- // Read metadata if required
300
- function(cb) {
301
- if (!readMetadata) {
302
- return cb();
303
- }
304
-
305
- self.ffprobe(0, function(err, data) {
306
- if (!err) {
307
- self._ffprobeData = data;
308
- }
309
-
310
- cb();
311
- });
312
- },
313
-
314
- // Check for flvtool2/flvmeta if necessary
315
- function(cb) {
316
- var flvmeta = self._outputs.some(function(output) {
317
- // Remove flvmeta flag on non-file output
318
- if (output.flags.flvmeta && !output.isFile) {
319
- self.logger.warn('Updating flv metadata is only supported for files');
320
- output.flags.flvmeta = false;
321
- }
322
-
323
- return output.flags.flvmeta;
324
- });
325
-
326
- if (flvmeta) {
327
- self._getFlvtoolPath(function(err) {
328
- cb(err);
329
- });
330
- } else {
331
- cb();
332
- }
333
- },
334
-
335
- // Build argument list
336
- function(cb) {
337
- var args;
338
- try {
339
- args = self._getArguments();
340
- } catch(e) {
341
- return cb(e);
342
- }
343
-
344
- cb(null, args);
345
- },
346
-
347
- // Add "-strict experimental" option where needed
348
- function(args, cb) {
349
- self.availableEncoders(function(err, encoders) {
350
- for (var i = 0; i < args.length; i++) {
351
- if (args[i] === '-acodec' || args[i] === '-vcodec') {
352
- i++;
353
-
354
- if ((args[i] in encoders) && encoders[args[i]].experimental) {
355
- args.splice(i + 1, 0, '-strict', 'experimental');
356
- i += 2;
357
- }
358
- }
359
- }
360
-
361
- cb(null, args);
362
- });
363
- }
364
- ], callback);
365
-
366
- if (!readMetadata) {
367
- // Read metadata as soon as 'progress' listeners are added
368
-
369
- if (this.listeners('progress').length > 0) {
370
- // Read metadata in parallel
371
- runFfprobe(this);
372
- } else {
373
- // Read metadata as soon as the first 'progress' listener is added
374
- this.once('newListener', function(event) {
375
- if (event === 'progress') {
376
- runFfprobe(this);
377
- }
378
- });
379
- }
380
- }
381
- };
382
-
383
-
384
- /**
385
- * Run ffmpeg command
386
- *
387
- * @method FfmpegCommand#run
388
- * @category Processing
389
- * @aliases exec,execute
390
- */
391
- proto.exec =
392
- proto.execute =
393
- proto.run = function() {
394
- var self = this;
395
-
396
- // Check if at least one output is present
397
- var outputPresent = this._outputs.some(function(output) {
398
- return 'target' in output;
399
- });
400
-
401
- if (!outputPresent) {
402
- throw new Error('No output specified');
403
- }
404
-
405
- // Get output stream if any
406
- var outputStream = this._outputs.filter(function(output) {
407
- return typeof output.target !== 'string';
408
- })[0];
409
-
410
- // Get input stream if any
411
- var inputStream = this._inputs.filter(function(input) {
412
- return typeof input.source !== 'string';
413
- })[0];
414
-
415
- // Ensure we send 'end' or 'error' only once
416
- var ended = false;
417
- function emitEnd(err, stdout, stderr) {
418
- if (!ended) {
419
- ended = true;
420
-
421
- if (err) {
422
- self.emit('error', err, stdout, stderr);
423
- } else {
424
- self.emit('end', stdout, stderr);
425
- }
426
- }
427
- }
428
-
429
- self._prepare(function(err, args) {
430
- if (err) {
431
- return emitEnd(err);
432
- }
433
-
434
- // Run ffmpeg
435
- self._spawnFfmpeg(
436
- args,
437
- {
438
- captureStdout: !outputStream,
439
- niceness: self.options.niceness,
440
- cwd: self.options.cwd,
441
- windowsHide: true
442
- },
443
-
444
- function processCB(ffmpegProc, stdoutRing, stderrRing) {
445
- self.ffmpegProc = ffmpegProc;
446
- self.emit('start', 'ffmpeg ' + args.join(' '));
447
-
448
- // Pipe input stream if any
449
- if (inputStream) {
450
- inputStream.source.on('error', function(err) {
451
- var reportingErr = new Error('Input stream error: ' + err.message);
452
- reportingErr.inputStreamError = err;
453
- emitEnd(reportingErr);
454
- ffmpegProc.kill();
455
- });
456
-
457
- inputStream.source.resume();
458
- inputStream.source.pipe(ffmpegProc.stdin);
459
-
460
- // Set stdin error handler on ffmpeg (prevents nodejs catching the error, but
461
- // ffmpeg will fail anyway, so no need to actually handle anything)
462
- ffmpegProc.stdin.on('error', function() {});
463
- }
464
-
465
- // Setup timeout if requested
466
- if (self.options.timeout) {
467
- self.processTimer = setTimeout(function() {
468
- var msg = 'process ran into a timeout (' + self.options.timeout + 's)';
469
-
470
- emitEnd(new Error(msg), stdoutRing.get(), stderrRing.get());
471
- ffmpegProc.kill();
472
- }, self.options.timeout * 1000);
473
- }
474
-
475
-
476
- if (outputStream) {
477
- // Pipe ffmpeg stdout to output stream
478
- ffmpegProc.stdout.pipe(outputStream.target, outputStream.pipeopts);
479
-
480
- // Handle output stream events
481
- outputStream.target.on('close', function() {
482
- self.logger.debug('Output stream closed, scheduling kill for ffmpeg process');
483
-
484
- // Don't kill process yet, to give a chance to ffmpeg to
485
- // terminate successfully first This is necessary because
486
- // under load, the process 'exit' event sometimes happens
487
- // after the output stream 'close' event.
488
- setTimeout(function() {
489
- emitEnd(new Error('Output stream closed'));
490
- ffmpegProc.kill();
491
- }, 20);
492
- });
493
-
494
- outputStream.target.on('error', function(err) {
495
- self.logger.debug('Output stream error, killing ffmpeg process');
496
- var reportingErr = new Error('Output stream error: ' + err.message);
497
- reportingErr.outputStreamError = err;
498
- emitEnd(reportingErr, stdoutRing.get(), stderrRing.get());
499
- ffmpegProc.kill('SIGKILL');
500
- });
501
- }
502
-
503
- // Setup stderr handling
504
- if (stderrRing) {
505
-
506
- // 'stderr' event
507
- if (self.listeners('stderr').length) {
508
- stderrRing.callback(function(line) {
509
- self.emit('stderr', line);
510
- });
511
- }
512
-
513
- // 'codecData' event
514
- if (self.listeners('codecData').length) {
515
- var codecDataSent = false;
516
- var codecObject = {};
517
-
518
- stderrRing.callback(function(line) {
519
- if (!codecDataSent)
520
- codecDataSent = utils.extractCodecData(self, line, codecObject);
521
- });
522
- }
523
-
524
- // 'progress' event
525
- if (self.listeners('progress').length) {
526
- stderrRing.callback(function(line) {
527
- utils.extractProgress(self, line);
528
- });
529
- }
530
- }
531
- },
532
-
533
- function endCB(err, stdoutRing, stderrRing) {
534
- clearTimeout(self.processTimer);
535
- delete self.ffmpegProc;
536
-
537
- if (err) {
538
- if (err.message.match(/ffmpeg exited with code/)) {
539
- // Add ffmpeg error message
540
- err.message += ': ' + utils.extractError(stderrRing.get());
541
- }
542
-
543
- emitEnd(err, stdoutRing.get(), stderrRing.get());
544
- } else {
545
- // Find out which outputs need flv metadata
546
- var flvmeta = self._outputs.filter(function(output) {
547
- return output.flags.flvmeta;
548
- });
549
-
550
- if (flvmeta.length) {
551
- self._getFlvtoolPath(function(err, flvtool) {
552
- if (err) {
553
- return emitEnd(err);
554
- }
555
-
556
- async.each(
557
- flvmeta,
558
- function(output, cb) {
559
- spawn(flvtool, ['-U', output.target], {windowsHide: true})
560
- .on('error', function(err) {
561
- cb(new Error('Error running ' + flvtool + ' on ' + output.target + ': ' + err.message));
562
- })
563
- .on('exit', function(code, signal) {
564
- if (code !== 0 || signal) {
565
- cb(
566
- new Error(flvtool + ' ' +
567
- (signal ? 'received signal ' + signal
568
- : 'exited with code ' + code)) +
569
- ' when running on ' + output.target
570
- );
571
- } else {
572
- cb();
573
- }
574
- });
575
- },
576
- function(err) {
577
- if (err) {
578
- emitEnd(err);
579
- } else {
580
- emitEnd(null, stdoutRing.get(), stderrRing.get());
581
- }
582
- }
583
- );
584
- });
585
- } else {
586
- emitEnd(null, stdoutRing.get(), stderrRing.get());
587
- }
588
- }
589
- }
590
- );
591
- });
592
-
593
- return this;
594
- };
595
-
596
-
597
- /**
598
- * Renice current and/or future ffmpeg processes
599
- *
600
- * Ignored on Windows platforms.
601
- *
602
- * @method FfmpegCommand#renice
603
- * @category Processing
604
- *
605
- * @param {Number} [niceness=0] niceness value between -20 (highest priority) and 20 (lowest priority)
606
- * @return FfmpegCommand
607
- */
608
- proto.renice = function(niceness) {
609
- if (!utils.isWindows) {
610
- niceness = niceness || 0;
611
-
612
- if (niceness < -20 || niceness > 20) {
613
- this.logger.warn('Invalid niceness value: ' + niceness + ', must be between -20 and 20');
614
- }
615
-
616
- niceness = Math.min(20, Math.max(-20, niceness));
617
- this.options.niceness = niceness;
618
-
619
- if (this.ffmpegProc) {
620
- var logger = this.logger;
621
- var pid = this.ffmpegProc.pid;
622
- var renice = spawn('renice', [niceness, '-p', pid], {windowsHide: true});
623
-
624
- renice.on('error', function(err) {
625
- logger.warn('could not renice process ' + pid + ': ' + err.message);
626
- });
627
-
628
- renice.on('exit', function(code, signal) {
629
- if (signal) {
630
- logger.warn('could not renice process ' + pid + ': renice was killed by signal ' + signal);
631
- } else if (code) {
632
- logger.warn('could not renice process ' + pid + ': renice exited with ' + code);
633
- } else {
634
- logger.info('successfully reniced process ' + pid + ' to ' + niceness + ' niceness');
635
- }
636
- });
637
- }
638
- }
639
-
640
- return this;
641
- };
642
-
643
-
644
- /**
645
- * Kill current ffmpeg process, if any
646
- *
647
- * @method FfmpegCommand#kill
648
- * @category Processing
649
- *
650
- * @param {String} [signal=SIGKILL] signal name
651
- * @return FfmpegCommand
652
- */
653
- proto.kill = function(signal) {
654
- if (!this.ffmpegProc) {
655
- this.logger.warn('No running ffmpeg process, cannot send signal');
656
- } else {
657
- this.ffmpegProc.kill(signal || 'SIGKILL');
658
- }
659
-
660
- return this;
661
- };
662
- };