Generate video thumbnails (#4084)
* Generate video thumbnails * import order
This commit is contained in:
		
							parent
							
								
									170b1bb4cc
								
							
						
					
					
						commit
						3040700005
					
				
					 7 changed files with 51 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -41,7 +41,7 @@ export default Vue.extend({
 | 
			
		|||
	computed: {
 | 
			
		||||
		imageStyle(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				'background-image': null // TODO `url(${this.video.thumbnailUrl})`
 | 
			
		||||
				'background-image': `url(${this.video.thumbnailUrl})`
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ export default Vue.extend({
 | 
			
		|||
	computed: {
 | 
			
		||||
		imageStyle(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				'background-image': null // TODO `url(${this.video.thumbnailUrl})`
 | 
			
		||||
				'background-image': `url(${this.video.thumbnailUrl})`
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ export default function(file: IDriveFile, thumbnail = false): string {
 | 
			
		|||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if (thumbnail) {
 | 
			
		||||
			return isImage ? `${config.drive_url}/${file._id}?thumbnail` : null;
 | 
			
		||||
			return `${config.drive_url}/${file._id}?thumbnail`;
 | 
			
		||||
		} else {
 | 
			
		||||
			return `${config.drive_url}/${file._id}?web`;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,7 +64,12 @@ export default async function(ctx: Koa.BaseContext) {
 | 
			
		|||
			const bucket = await getDriveFileThumbnailBucket();
 | 
			
		||||
			ctx.body = bucket.openDownloadStream(thumb._id);
 | 
			
		||||
		} else {
 | 
			
		||||
			await sendRaw();
 | 
			
		||||
			if (file.contentType.startsWith('image/')) {
 | 
			
		||||
				await sendRaw();
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.status = 404;
 | 
			
		||||
				await send(ctx as any, '/dummy.png', { root: assets });
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else if ('web' in ctx.query) {
 | 
			
		||||
		const web = await DriveFileWebpublic.findOne({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
 | 
			
		|||
import driveChart from '../../chart/drive';
 | 
			
		||||
import perUserDriveChart from '../../chart/per-user-drive';
 | 
			
		||||
import fetchMeta from '../../misc/fetch-meta';
 | 
			
		||||
import { GenerateVideoThumbnail } from './generate-video-thumbnail';
 | 
			
		||||
 | 
			
		||||
const log = debug('misskey:drive:add-file');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +119,14 @@ async function save(path: string, name: string, type: string, hash: string, size
 | 
			
		|||
 | 
			
		||||
		thumbnailExt = 'png';
 | 
			
		||||
		thumbnailType = 'image/png';
 | 
			
		||||
	} else if (type.startsWith('video/')) {
 | 
			
		||||
		try {
 | 
			
		||||
			thumbnail = await GenerateVideoThumbnail(path);
 | 
			
		||||
			thumbnailExt = 'png';
 | 
			
		||||
			thumbnailType = 'image/png';
 | 
			
		||||
		} catch (e) {
 | 
			
		||||
			console.log(`GenerateVideoThumbnail failed: ${e}`);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// #endregion thumbnail
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								src/services/drive/generate-video-thumbnail.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/services/drive/generate-video-thumbnail.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
import * as fs from 'fs';
 | 
			
		||||
import * as tmp from 'tmp';
 | 
			
		||||
const ThumbnailGenerator = require('video-thumbnail-generator').default;
 | 
			
		||||
 | 
			
		||||
export async function GenerateVideoThumbnail(path: string): Promise<Buffer> {
 | 
			
		||||
	const [outDir, cleanup] = await new Promise<[string, any]>((res, rej) => {
 | 
			
		||||
		tmp.dir((e, path, cleanup) => {
 | 
			
		||||
			if (e) return rej(e);
 | 
			
		||||
			res([path, cleanup]);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const tg = new ThumbnailGenerator({
 | 
			
		||||
		sourcePath: path,
 | 
			
		||||
		thumbnailPath: outDir,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	await tg.generateOneByPercent(10, {
 | 
			
		||||
		size: '498x280',
 | 
			
		||||
		filename: 'output.png',
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const outPath = `${outDir}/output.png`;
 | 
			
		||||
 | 
			
		||||
	const buffer = fs.readFileSync(outPath);
 | 
			
		||||
 | 
			
		||||
	// cleanup
 | 
			
		||||
	fs.unlinkSync(outPath);
 | 
			
		||||
	cleanup();
 | 
			
		||||
 | 
			
		||||
	return buffer;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue