<img [src]="actor.avatarUrl" alt="Avatar" />
<div class="actor-img-edit-container">
- <div class="actor-img-edit-button" [ngbTooltip]="'(extensions: '+ avatarExtensions +', '+ maxSizeText +': '+ maxAvatarSizeInBytes +')'" placement="right" container="body">
+ <div class="actor-img-edit-button" [ngbTooltip]="avatarFormat"
+ placement="right" container="body">
<my-global-icon iconName="edit"></my-global-icon>
<label for="avatarfile" i18n>Change your avatar</label>
<input #avatarfileInput type="file" title=" " name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange()"/>
@Output() avatarChange = new EventEmitter<FormData>()
- maxSizeText: string
-
private serverConfig: ServerConfig
constructor (
private serverService: ServerService,
private notifier: Notifier
- ) {
- this.maxSizeText = $localize`max size`
- }
+ ) { }
ngOnInit (): void {
this.serverConfig = this.serverService.getTmpConfig()
get avatarExtensions () {
return this.serverConfig.avatar.file.extensions.join(', ')
}
+
+ get avatarFormat () {
+ return `${$localize`max size`}: 192*192px, ${this.maxAvatarSizeInBytes} ${$localize`extensions`}: ${this.avatarExtensions}`
+ }
}
})
}
+function processGIF (
+ path: string,
+ destination: string,
+ newSize: { width: number, height: number },
+ keepOriginal = false
+): Promise<void> {
+ return new Promise<void>(async (res, rej) => {
+ if (path === destination) {
+ throw new Error('FFmpeg needs an input path different that the output path.')
+ }
+
+ logger.debug('Processing gif %s to %s.', path, destination)
+
+ try {
+ const command = ffmpeg(path)
+ .fps(20)
+ .size(`${newSize.width}x${newSize.height}`)
+ .output(destination)
+
+ command.on('error', (err, stdout, stderr) => {
+ logger.error('Error in ffmpeg gif resizing process.', { stdout, stderr })
+ return rej(err)
+ })
+ .on('end', async () => {
+ if (keepOriginal !== true) await remove(path)
+ res()
+ })
+ .run()
+ } catch (err) {
+ return rej(err)
+ }
+ })
+}
+
function runLiveTranscoding (rtmpUrl: string, outPath: string, resolutions: number[], fps, deleteSegments: boolean) {
const command = getFFmpeg(rtmpUrl)
command.inputOption('-fflags nobuffer')
getAudioStreamCodec,
runLiveMuxing,
convertWebPToJPG,
+ processGIF,
getVideoStreamSize,
getVideoFileResolution,
getMetadataFromFile,
+import { extname } from 'path'
import { remove, rename } from 'fs-extra'
-import { convertWebPToJPG } from './ffmpeg-utils'
+import { convertWebPToJPG, processGIF } from './ffmpeg-utils'
import { logger } from './logger'
const Jimp = require('jimp')
newSize: { width: number, height: number },
keepOriginal = false
) {
+ const extension = extname(path)
+
+ // Use FFmpeg to process GIF
+ if (extension === '.gif') {
+ return processGIF(path, destination, newSize, keepOriginal)
+ }
+
if (path === destination) {
throw new Error('Jimp needs an input path different that the output path.')
}
PRIVATE_KEY: { min: 10, max: 5000 }, // Length
URL: { min: 3, max: 2000 }, // Length
AVATAR: {
- EXTNAME: [ '.png', '.jpeg', '.jpg' ],
+ EXTNAME: [ '.png', '.jpeg', '.jpg', '.gif' ],
FILE_SIZE: {
max: 2 * 1024 * 1024 // 2MB
}