Add pixel size to tooltip and gif support with FFmpeg for avatar upload (#3329)
* Add avatar pixel size upload in tooltip * Add gif support for avatar * Add ffmpeg GIF process Co-authored-by: kimsible <kimsible@users.noreply.github.com>
This commit is contained in:
parent
c07fac202d
commit
123f619336
|
@ -4,7 +4,8 @@
|
|||
<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()"/>
|
||||
|
|
|
@ -17,16 +17,12 @@ export class ActorAvatarInfoComponent implements OnInit {
|
|||
|
||||
@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()
|
||||
|
@ -58,4 +54,8 @@ export class ActorAvatarInfoComponent implements OnInit {
|
|||
get avatarExtensions () {
|
||||
return this.serverConfig.avatar.file.extensions.join(', ')
|
||||
}
|
||||
|
||||
get avatarFormat () {
|
||||
return `${$localize`max size`}: 192*192px, ${this.maxAvatarSizeInBytes} ${$localize`extensions`}: ${this.avatarExtensions}`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -355,6 +355,40 @@ function convertWebPToJPG (path: string, destination: string): Promise<void> {
|
|||
})
|
||||
}
|
||||
|
||||
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')
|
||||
|
@ -474,6 +508,7 @@ export {
|
|||
getAudioStreamCodec,
|
||||
runLiveMuxing,
|
||||
convertWebPToJPG,
|
||||
processGIF,
|
||||
getVideoStreamSize,
|
||||
getVideoFileResolution,
|
||||
getMetadataFromFile,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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')
|
||||
|
@ -10,6 +11,13 @@ async function processImage (
|
|||
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.')
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ const CONSTRAINTS_FIELDS = {
|
|||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue