+import { logger, loggerTagsFactory } from './logger'
+
+const lTags = loggerTagsFactory('ffmpeg')
+
+/**
+ *
+ * Functions that run transcoding/muxing ffmpeg processes
+ * Mainly called by lib/video-transcoding.ts and lib/live-manager.ts
+ *
+ */
+
+// ---------------------------------------------------------------------------
+// Encoder options
+// ---------------------------------------------------------------------------
+
+type StreamType = 'audio' | 'video'
+
+// ---------------------------------------------------------------------------
+// Encoders support
+// ---------------------------------------------------------------------------
+
+// Detect supported encoders by ffmpeg
+let supportedEncoders: Map<string, boolean>
+async function checkFFmpegEncoders (peertubeAvailableEncoders: AvailableEncoders): Promise<Map<string, boolean>> {
+ if (supportedEncoders !== undefined) {
+ return supportedEncoders
+ }
+
+ const getAvailableEncodersPromise = promisify0(getAvailableEncoders)
+ const availableFFmpegEncoders = await getAvailableEncodersPromise()
+
+ const searchEncoders = new Set<string>()
+ for (const type of [ 'live', 'vod' ]) {
+ for (const streamType of [ 'audio', 'video' ]) {
+ for (const encoder of peertubeAvailableEncoders.encodersToTry[type][streamType]) {
+ searchEncoders.add(encoder)
+ }
+ }
+ }
+
+ supportedEncoders = new Map<string, boolean>()
+
+ for (const searchEncoder of searchEncoders) {
+ supportedEncoders.set(searchEncoder, availableFFmpegEncoders[searchEncoder] !== undefined)
+ }
+
+ logger.info('Built supported ffmpeg encoders.', { supportedEncoders, searchEncoders, ...lTags() })
+
+ return supportedEncoders
+}
+
+function resetSupportedEncoders () {
+ supportedEncoders = undefined
+}
+
+// ---------------------------------------------------------------------------
+// Image manipulation
+// ---------------------------------------------------------------------------
+
+function convertWebPToJPG (path: string, destination: string): Promise<void> {
+ const command = ffmpeg(path, { niceness: FFMPEG_NICE.THUMBNAIL })
+ .output(destination)
+
+ return runCommand({ command, silent: true })
+}
+
+function processGIF (
+ path: string,
+ destination: string,
+ newSize: { width: number, height: number }
+): Promise<void> {
+ const command = ffmpeg(path, { niceness: FFMPEG_NICE.THUMBNAIL })
+ .fps(20)
+ .size(`${newSize.width}x${newSize.height}`)
+ .output(destination)
+
+ return runCommand({ command })
+}