2023-07-27 08:31:52 +03:00
|
|
|
/*
|
2024-02-13 17:59:27 +02:00
|
|
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
2023-07-27 08:31:52 +03:00
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-09-17 21:27:08 +03:00
|
|
|
import { Inject, Injectable } from '@nestjs/common';
|
|
|
|
import FFmpeg from 'fluent-ffmpeg';
|
|
|
|
import { DI } from '@/di-symbols.js';
|
2022-09-20 23:33:11 +03:00
|
|
|
import type { Config } from '@/config.js';
|
2022-09-17 21:27:08 +03:00
|
|
|
import { ImageProcessingService } from '@/core/ImageProcessingService.js';
|
|
|
|
import type { IImage } from '@/core/ImageProcessingService.js';
|
|
|
|
import { createTempDir } from '@/misc/create-temp.js';
|
2022-12-04 08:03:09 +02:00
|
|
|
import { bindThis } from '@/decorators.js';
|
2023-02-12 02:13:47 +02:00
|
|
|
import { appendQuery, query } from '@/misc/prelude/url.js';
|
2022-09-17 21:27:08 +03:00
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class VideoProcessingService {
|
|
|
|
constructor(
|
|
|
|
@Inject(DI.config)
|
|
|
|
private config: Config,
|
|
|
|
|
|
|
|
private imageProcessingService: ImageProcessingService,
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
2022-12-04 08:03:09 +02:00
|
|
|
@bindThis
|
2022-09-17 21:27:08 +03:00
|
|
|
public async generateVideoThumbnail(source: string): Promise<IImage> {
|
|
|
|
const [dir, cleanup] = await createTempDir();
|
2023-07-08 01:08:16 +03:00
|
|
|
|
2022-09-17 21:27:08 +03:00
|
|
|
try {
|
|
|
|
await new Promise((res, rej) => {
|
|
|
|
FFmpeg({
|
|
|
|
source,
|
|
|
|
})
|
|
|
|
.on('end', res)
|
|
|
|
.on('error', rej)
|
|
|
|
.screenshot({
|
|
|
|
folder: dir,
|
|
|
|
filename: 'out.png', // must have .png extension
|
|
|
|
count: 1,
|
|
|
|
timestamps: ['5%'],
|
|
|
|
});
|
|
|
|
});
|
2022-12-24 17:15:48 +02:00
|
|
|
|
2023-04-02 18:49:07 +03:00
|
|
|
return await this.imageProcessingService.convertToWebp(`${dir}/out.png`, 498, 422);
|
2022-09-17 21:27:08 +03:00
|
|
|
} finally {
|
|
|
|
cleanup();
|
|
|
|
}
|
|
|
|
}
|
2023-02-12 02:13:47 +02:00
|
|
|
|
|
|
|
@bindThis
|
|
|
|
public getExternalVideoThumbnailUrl(url: string): string | null {
|
|
|
|
if (this.config.videoThumbnailGenerator == null) return null;
|
|
|
|
|
|
|
|
return appendQuery(
|
|
|
|
`${this.config.videoThumbnailGenerator}/thumbnail.webp`,
|
|
|
|
query({
|
|
|
|
thumbnail: '1',
|
|
|
|
url,
|
2023-07-19 05:27:50 +03:00
|
|
|
}),
|
2023-02-17 03:56:59 +02:00
|
|
|
);
|
2023-02-12 02:13:47 +02:00
|
|
|
}
|
2022-09-17 21:27:08 +03:00
|
|
|
}
|
|
|
|
|