]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/helpers/image-utils.ts
emit more specific status codes on video upload (#3423)
[github/Chocobozzz/PeerTube.git] / server / helpers / image-utils.ts
index da3285b13da7c3cfc902abfcfeab2f46564ab913..3ebf073058bd1f85e00abc49d5a59748ed4c81a3 100644 (file)
@@ -1,32 +1,32 @@
-import 'multer'
-import * as sharp from 'sharp'
-import { move, remove } from 'fs-extra'
+import { remove, rename } from 'fs-extra'
+import { extname } from 'path'
+import { convertWebPToJPG, processGIF } from './ffmpeg-utils'
+import { logger } from './logger'
+
+const Jimp = require('jimp')
 
 async function processImage (
-  physicalFile: { path: string },
+  path: string,
   destination: string,
-  newSize: { width: number, height: number }
+  newSize: { width: number, height: number },
+  keepOriginal = false
 ) {
-  if (physicalFile.path === destination) {
-    throw new Error('Sharp needs an input path different that the output path.')
-  }
-
-  const sharpInstance = sharp(physicalFile.path)
-  const metadata = await sharpInstance.metadata()
+  const extension = extname(path)
 
-  // No need to resize
-  if (metadata.width === newSize.width && metadata.height === newSize.height) {
-    await move(physicalFile.path, destination, { overwrite: true })
-    return
+  if (path === destination) {
+    throw new Error('Jimp/FFmpeg needs an input path different that the output path.')
   }
 
-  await remove(destination)
+  logger.debug('Processing image %s to %s.', path, destination)
 
-  await sharpInstance
-    .resize(newSize.width, newSize.height)
-    .toFile(destination)
+  // Use FFmpeg to process GIF
+  if (extension === '.gif') {
+    await processGIF(path, destination, newSize)
+  } else {
+    await jimpProcessor(path, destination, newSize)
+  }
 
-  await remove(physicalFile.path)
+  if (keepOriginal !== true) await remove(path)
 }
 
 // ---------------------------------------------------------------------------
@@ -34,3 +34,28 @@ async function processImage (
 export {
   processImage
 }
+
+// ---------------------------------------------------------------------------
+
+async function jimpProcessor (path: string, destination: string, newSize: { width: number, height: number }) {
+  let jimpInstance: any
+
+  try {
+    jimpInstance = await Jimp.read(path)
+  } catch (err) {
+    logger.debug('Cannot read %s with jimp. Try to convert the image using ffmpeg first.', path, { err })
+
+    const newName = path + '.jpg'
+    await convertWebPToJPG(path, newName)
+    await rename(newName, path)
+
+    jimpInstance = await Jimp.read(path)
+  }
+
+  await remove(destination)
+
+  await jimpInstance
+    .resize(newSize.width, newSize.height)
+    .quality(80)
+    .writeAsync(destination)
+}