From 48e8ee440bcff712710666861262b0a6492a3794 Mon Sep 17 00:00:00 2001
From: MeiMei <30769358+mei23@users.noreply.github.com>
Date: Tue, 18 Aug 2020 22:48:52 +0900
Subject: [PATCH] =?UTF-8?q?WebP=E3=81=AE=E3=82=A2=E3=83=8B=E3=83=A1?=
 =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=8C=E5=A4=B1=E3=82=8F?=
 =?UTF-8?q?=E3=82=8C=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3=20Fix=20?=
 =?UTF-8?q?#6625=20(#6649)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/server/proxy/proxy-media.ts |  2 +-
 src/services/drive/add-file.ts  | 47 ++++++++++++++++++++++++---------
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/src/server/proxy/proxy-media.ts b/src/server/proxy/proxy-media.ts
index d035a84d9e..4373cc20f5 100644
--- a/src/server/proxy/proxy-media.ts
+++ b/src/server/proxy/proxy-media.ts
@@ -21,7 +21,7 @@ export async function proxyMedia(ctx: Koa.Context) {
 
 		let image: IImage;
 
-		if ('static' in ctx.query && ['image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng'].includes(mime)) {
+		if ('static' in ctx.query && ['image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp'].includes(mime)) {
 			image = await convertToPng(path, 498, 280);
 		} else if ('preview' in ctx.query && ['image/jpeg', 'image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng'].includes(mime)) {
 			image = await convertToJpeg(path, 200, 200);
diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts
index 91bbace481..fbd2f76ddc 100644
--- a/src/services/drive/add-file.ts
+++ b/src/services/drive/add-file.ts
@@ -7,7 +7,7 @@ import { deleteFile } from './delete-file';
 import { fetchMeta } from '../../misc/fetch-meta';
 import { GenerateVideoThumbnail } from './generate-video-thumbnail';
 import { driveLogger } from './logger';
-import { IImage, convertToJpeg, convertToWebp, convertToPng, convertToPngOrJpeg } from './image-processor';
+import { IImage, convertSharpToJpeg, convertSharpToWebp, convertSharpToPng, convertSharpToPngOrJpeg } from './image-processor';
 import { contentDisposition } from '../../misc/content-disposition';
 import { getFileInfo } from '../../misc/get-file-info';
 import { DriveFiles, DriveFolders, Users, Instances, UserProfiles } from '../../models';
@@ -19,6 +19,7 @@ import { genId } from '../../misc/gen-id';
 import { isDuplicateKeyValueError } from '../../misc/is-duplicate-key-value-error';
 import * as S3 from 'aws-sdk/clients/s3';
 import { getS3 } from './s3';
+import * as sharp from 'sharp';
 
 const logger = driveLogger.createSubLogger('register', 'yellow');
 
@@ -143,6 +144,34 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
  * @param generateWeb Generate webpublic or not
  */
 export async function generateAlts(path: string, type: string, generateWeb: boolean) {
+	if (type.startsWith('video/')) {
+		try {
+			const thumbnail = await GenerateVideoThumbnail(path);
+			return {
+				webpublic: null,
+				thumbnail
+			};
+		} catch (e) {
+			logger.warn(`GenerateVideoThumbnail failed: ${e}`);
+			return {
+				webpublic: null,
+				thumbnail: null
+			};
+		}
+	}
+
+	const img = sharp(path);
+	const metadata = await img.metadata();
+	const isAnimated = metadata.pages && metadata.pages > 1;
+
+	// skip animated
+	if (isAnimated) {
+		return {
+			webpublic: null,
+			thumbnail: null
+		};
+	}
+
 	// #region webpublic
 	let webpublic: IImage | null = null;
 
@@ -151,11 +180,11 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 
 		try {
 			if (['image/jpeg'].includes(type)) {
-				webpublic = await convertToJpeg(path, 2048, 2048);
+				webpublic = await convertSharpToJpeg(img, 2048, 2048);
 			} else if (['image/webp'].includes(type)) {
-				webpublic = await convertToWebp(path, 2048, 2048);
+				webpublic = await convertSharpToWebp(img, 2048, 2048);
 			} else if (['image/png'].includes(type)) {
-				webpublic = await convertToPng(path, 2048, 2048);
+				webpublic = await convertSharpToPng(img, 2048, 2048);
 			} else {
 				logger.debug(`web image not created (not an required image)`);
 			}
@@ -172,15 +201,9 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 
 	try {
 		if (['image/jpeg', 'image/webp'].includes(type)) {
-			thumbnail = await convertToJpeg(path, 498, 280);
+			thumbnail = await convertSharpToJpeg(img, 498, 280);
 		} else if (['image/png'].includes(type)) {
-			thumbnail = await convertToPngOrJpeg(path, 498, 280);
-		} else if (type.startsWith('video/')) {
-			try {
-				thumbnail = await GenerateVideoThumbnail(path);
-			} catch (e) {
-				logger.warn(`GenerateVideoThumbnail failed: ${e}`);
-			}
+			thumbnail = await convertSharpToPngOrJpeg(img, 498, 280);
 		} else {
 			logger.debug(`thumbnail not created (not an required file)`);
 		}