Recherche avancée

Médias (0)

Mot : - Tags -/clipboard

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (88)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

  • Gestion de la ferme

    2 mars 2010, par

    La ferme est gérée dans son ensemble par des "super admins".
    Certains réglages peuvent être fais afin de réguler les besoins des différents canaux.
    Dans un premier temps il utilise le plugin "Gestion de mutualisation"

  • Gestion des droits de création et d’édition des objets

    8 février 2011, par

    Par défaut, beaucoup de fonctionnalités sont limitées aux administrateurs mais restent configurables indépendamment pour modifier leur statut minimal d’utilisation notamment : la rédaction de contenus sur le site modifiables dans la gestion des templates de formulaires ; l’ajout de notes aux articles ; l’ajout de légendes et d’annotations sur les images ;

Sur d’autres sites (8048)

  • SegFault while freeing nvenc hwdevice_ctx

    23 février 2024, par camelCase

    For a project, I created a class encoding the output of an OpenGL renderbuffer object using h264_nvenc. Unfortunately, tidying up doesn't work, and the program crashes with a SegFault. The reason is accessing an unaccessable memory region, happening twice in the final lines (see below) when calling av_buffer_unref( &_hwDeviceRefCtx ) and implicitely also during avcodec_free_context( &_pCodecCtx ), but both calls are required for shutting down.

    


    The (in this case relevant) valgrind-output is

    


    Invalid read of size 8
   at 0x48AD987: UnknownInlinedFun (buffer.c:121)
   by 0x48AD987: UnknownInlinedFun (buffer.c:144)
   by 0x48AD987: av_buffer_unref (buffer.c:139)
   by 0x5D06D7A: avcodec_close (avcodec.c:486)
   by 0x628DD7D: avcodec_free_context (options.c:175)
   by 0x10A863: main (main.cpp:115)
 Address 0x17812700 is 0 bytes inside a block of size 24 free'd
   at 0x484488F: free (vg_replace_malloc.c:985)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:127)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:144)
   by 0x48AD98F: av_buffer_unref (buffer.c:139)
   by 0x48BE098: hwframe_ctx_free (hwcontext.c:240)
   by 0x48AD9A6: UnknownInlinedFun (buffer.c:133)
   by 0x48AD9A6: UnknownInlinedFun (buffer.c:144)
   by 0x48AD9A6: av_buffer_unref (buffer.c:139)
   by 0x5D06D0A: UnknownInlinedFun (decode.c:1261)
   by 0x5D06D0A: avcodec_close (avcodec.c:465)
   by 0x628DD7D: avcodec_free_context (options.c:175)
   by 0x10A863: main (main.cpp:115)
 Block was alloc'd at
   at 0x4849366: posix_memalign (vg_replace_malloc.c:2099)
   by 0x48D9BD5: av_malloc (mem.c:105)
   by 0x48D9DAD: av_mallocz (mem.c:256)
   by 0x48AD8DD: UnknownInlinedFun (buffer.c:44)
   by 0x48AD8DD: av_buffer_create (buffer.c:64)
   by 0x48BDDEB: av_hwdevice_ctx_alloc (hwcontext.c:179)
   by 0x48BDF29: av_hwdevice_ctx_create (hwcontext.c:622)
   by 0x10A482: main (main.cpp:43)

Invalid free() / delete / delete[] / realloc()
   at 0x484488F: free (vg_replace_malloc.c:985)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:127)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:144)
   by 0x48AD98F: av_buffer_unref (buffer.c:139)
   by 0x5D06D7A: avcodec_close (avcodec.c:486)
   by 0x628DD7D: avcodec_free_context (options.c:175)
   by 0x10A863: main (main.cpp:115)
 Address 0x17812700 is 0 bytes inside a block of size 24 free'd
   at 0x484488F: free (vg_replace_malloc.c:985)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:127)
   by 0x48AD98F: UnknownInlinedFun (buffer.c:144)
   by 0x48AD98F: av_buffer_unref (buffer.c:139)
   by 0x48BE098: hwframe_ctx_free (hwcontext.c:240)
   by 0x48AD9A6: UnknownInlinedFun (buffer.c:133)
   by 0x48AD9A6: UnknownInlinedFun (buffer.c:144)
   by 0x48AD9A6: av_buffer_unref (buffer.c:139)
   by 0x5D06D0A: UnknownInlinedFun (decode.c:1261)
   by 0x5D06D0A: avcodec_close (avcodec.c:465)
   by 0x628DD7D: avcodec_free_context (options.c:175)
   by 0x10A863: main (main.cpp:115)
 Block was alloc'd at
   at 0x4849366: posix_memalign (vg_replace_malloc.c:2099)
   by 0x48D9BD5: av_malloc (mem.c:105)
   by 0x48D9DAD: av_mallocz (mem.c:256)
   by 0x48AD8DD: UnknownInlinedFun (buffer.c:44)
   by 0x48AD8DD: av_buffer_create (buffer.c:64)
   by 0x48BDDEB: av_hwdevice_ctx_alloc (hwcontext.c:179)
   by 0x48BDF29: av_hwdevice_ctx_create (hwcontext.c:622)
   by 0x10A482: main (main.cpp:43)


    


    that is also duplicated (due to the calls to avcodec_free_context() and av_buffer_unref()).

    


    The question is : How can I fix this ?

    


    The (more or less) minimal (not) working example reads

    


    #include <string>&#xA;&#xA;extern "C" {&#xA;  #include <libavutil></libavutil>opt.h>&#xA;  #include <libavcodec></libavcodec>avcodec.h>&#xA;  #include <libavformat></libavformat>avformat.h>&#xA;  #include <libavutil></libavutil>hwcontext.h>&#xA;  #include <libavutil></libavutil>pixdesc.h>&#xA;  #include <libavutil></libavutil>hwcontext_cuda.h>&#xA;}&#xA;&#xA;//(former) libx264 encoding based on https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/muxing.c&#xA;//update to h264_nvenc with a lot of help from https://stackoverflow.com/questions/49862610/opengl-to-ffmpeg-encode&#xA;//and some additional info of https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/vaapi_encode.c&#xA;&#xA;int main() {&#xA;    const int _SrcImageWidth=640;&#xA;    const int _SrcImageHeight=480;&#xA;    &#xA;    const AVOutputFormat *_oFmt = nullptr;&#xA;    AVFormatContext *_oFmtCtx = nullptr;&#xA;    &#xA;    const AVCodec *_pCodec = nullptr;&#xA;    AVCodecContext *_pCodecCtx = nullptr;&#xA;    &#xA;    AVFrame* _frame;&#xA;    AVPacket* _packet;&#xA;    AVStream* _stream;&#xA;    &#xA;    AVBufferRef *_hwDeviceRefCtx = nullptr;&#xA;    const CUcontext* _cudaCtx;&#xA;    &#xA;    const std::string _OutFileName = "output.mkv";&#xA;    &#xA;    //constructor part&#xA;    int ret;&#xA;&#xA;    //output format context      &#xA;    avformat_alloc_output_context2( &amp;_oFmtCtx, nullptr, nullptr, _OutFileName.c_str() );&#xA;    _oFmt = _oFmtCtx->oformat;&#xA;&#xA;    //hardware format context&#xA;    ret = av_hwdevice_ctx_create( &amp;_hwDeviceRefCtx, AV_HWDEVICE_TYPE_CUDA, "NVIDIA GeForce RTX 4070", nullptr, 0 );&#xA;&#xA;    //hardware frame context for device buffer allocation&#xA;    AVBufferRef* hwFrameRefCtx = av_hwframe_ctx_alloc( _hwDeviceRefCtx );&#xA;    AVHWFramesContext* hwFrameCtx = (AVHWFramesContext*) (hwFrameRefCtx->data);&#xA;    hwFrameCtx->width = _SrcImageWidth;&#xA;    hwFrameCtx->height = _SrcImageHeight;&#xA;    hwFrameCtx->sw_format = AV_PIX_FMT_0BGR32;&#xA;    hwFrameCtx->format = AV_PIX_FMT_CUDA;&#xA;    hwFrameCtx->device_ref = _hwDeviceRefCtx;&#xA;    hwFrameCtx->device_ctx = (AVHWDeviceContext*) _hwDeviceRefCtx->data;&#xA;&#xA;    ret = av_hwframe_ctx_init( hwFrameRefCtx );&#xA;&#xA;    //get cuda context&#xA;    const AVHWDeviceContext* hwDeviceCtx = (AVHWDeviceContext*)(_hwDeviceRefCtx->data);&#xA;    const AVCUDADeviceContext* cudaDeviceCtx = (AVCUDADeviceContext*)(hwDeviceCtx->hwctx);&#xA;    _cudaCtx = &amp;(cudaDeviceCtx->cuda_ctx);&#xA;&#xA;    //codec context&#xA;    _pCodec = avcodec_find_encoder_by_name( "h264_nvenc" );&#xA;&#xA;    _packet = av_packet_alloc();&#xA;&#xA;    _stream = avformat_new_stream( _oFmtCtx, nullptr );&#xA;    _stream->id = _oFmtCtx->nb_streams - 1;&#xA;    _pCodecCtx = avcodec_alloc_context3( _pCodec );&#xA;&#xA;    _pCodecCtx->qmin = 18;&#xA;    _pCodecCtx->qmax = 20;&#xA;    _pCodecCtx->width = _SrcImageWidth;&#xA;    _pCodecCtx->height = _SrcImageHeight;&#xA;    _pCodecCtx->framerate = (AVRational) {25,1};&#xA;    _pCodecCtx->time_base = (AVRational) {1,25};&#xA;    _stream->time_base = _pCodecCtx->time_base;&#xA;    _pCodecCtx->gop_size = 12; //I-Frame every at most 12 frames&#xA;    _pCodecCtx->max_b_frames = 2;&#xA;    _pCodecCtx->pix_fmt = AV_PIX_FMT_CUDA; //required to use renderbuffer as src&#xA;    _pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;    _pCodecCtx->sw_pix_fmt = AV_PIX_FMT_0BGR32; &#xA;    _pCodecCtx->hw_device_ctx = _hwDeviceRefCtx;&#xA;    _pCodecCtx->hw_frames_ctx = av_buffer_ref( hwFrameRefCtx );&#xA;    av_opt_set(_pCodecCtx->priv_data, "preset", "p7", 0);&#xA;    av_opt_set(_pCodecCtx->priv_data, "rc", "vbr", 0);&#xA;    if( _oFmtCtx->oformat->flags &amp; AVFMT_GLOBALHEADER ) {&#xA;        _pCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;    }&#xA;&#xA;    ret = avcodec_open2( _pCodecCtx, _pCodec, nullptr );&#xA;    avcodec_parameters_from_context( _stream->codecpar, _pCodecCtx );&#xA;&#xA;    if (!(_oFmtCtx->oformat->flags &amp; AVFMT_NOFILE)) {&#xA;        ret = avio_open(&amp;_oFmtCtx->pb, _OutFileName.c_str(), AVIO_FLAG_WRITE);&#xA;    }&#xA;    ret = avformat_write_header( _oFmtCtx, nullptr );&#xA;&#xA;    //use hardware frame from above&#xA;    _frame = av_frame_alloc();&#xA;    ret = av_hwframe_get_buffer( _pCodecCtx->hw_frames_ctx, _frame, 0 );&#xA;    _frame->pts = 1;&#xA;&#xA;    av_buffer_unref( &amp;hwFrameRefCtx );&#xA;&#xA;    //destructor part&#xA;    av_frame_free( &amp;_frame );&#xA;    av_packet_free( &amp;_packet );&#xA;&#xA;    av_write_trailer( _oFmtCtx );&#xA;    avio_closep( &amp;_oFmtCtx->pb );&#xA;&#xA;    avformat_free_context( _oFmtCtx );&#xA;&#xA;    avcodec_free_context( &amp;_pCodecCtx );&#xA;    av_buffer_unref( &amp;_hwDeviceRefCtx );&#xA;&#xA;    return 0;&#xA;}&#xA;</string>

    &#xA;

    and compiles with (linux user)

    &#xA;

    g&#x2B;&#x2B; -lavutil -lavformat -lavcodec -lz -lavutil -lswscale -lswresample -lm -ggdb3 -I/opt/cuda/include main.cpp&#xA;

    &#xA;

    Thanks in advance !

    &#xA;

  • FFMPEG Concatenating videos with same 25fps results in output file with 3.554fps

    5 juin 2024, par Kendra Broom

    I created an AWS Lambda function in node.js 18 that is using a static, ver 7 build of FFmpeg located in a lambda layer. Unfortunately it's just the ffmpeg build and doesn't include ffprobe.

    &#xA;

    I have an mp4 audio file in one S3 bucket and a wav audio file in a second S3 bucket. I'm uploading the output file to a third S3 bucket.

    &#xA;

    Specs on the files (please let me know if any more info is needed)

    &#xA;

    Audio :&#xA;wav, 13kbps, aac (LC), 6:28 duration

    &#xA;

    Video :&#xA;mp4, 1280x720 resolution, 25 frame rate, h264 codec, 3:27 duration

    &#xA;

    Goal :&#xA;Create blank video to fill in the duration gaps so the full audio is covered before and after the mp4 video (using timestamps and duration). Strip the mp4 audio and use the wav audio only. Output should be an mp4 video with the wav audio playing over it and blank video for 27 seconds (based on timestamp) until mp4 video plays for 3:27, and then blank video to cover the rest of the audio until 6:28.

    &#xA;

    Actual Result :&#xA;An mp4 file with 3.554 frame rate and 10:06 duration.

    &#xA;

    import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";&#xA;import { createWriteStream, createReadStream, promises as fsPromises } from &#x27;fs&#x27;;&#xA;import { exec } from &#x27;child_process&#x27;;&#xA;import { promisify } from &#x27;util&#x27;;&#xA;import { basename } from &#x27;path&#x27;;&#xA;&#xA;const execAsync = promisify(exec);&#xA;&#xA;const s3 = new S3Client({ region: &#x27;us-east-1&#x27; });&#xA;&#xA;async function downloadFileFromS3(bucket, key, downloadPath) {&#xA;    const getObjectParams = { Bucket: bucket, Key: key };&#xA;    const command = new GetObjectCommand(getObjectParams);&#xA;    const { Body } = await s3.send(command);&#xA;    return new Promise((resolve, reject) => {&#xA;        const fileStream = createWriteStream(downloadPath);&#xA;        Body.pipe(fileStream);&#xA;        Body.on(&#x27;error&#x27;, reject);&#xA;        fileStream.on(&#x27;finish&#x27;, resolve);&#xA;    });&#xA;}&#xA;&#xA;async function uploadFileToS3(bucket, key, filePath) {&#xA;    const fileStream = createReadStream(filePath);&#xA;    const uploadParams = { Bucket: bucket, Key: key, Body: fileStream };&#xA;    try {&#xA;        await s3.send(new PutObjectCommand(uploadParams));&#xA;        console.log(`File uploaded successfully to ${bucket}/${key}`);&#xA;    } catch (err) {&#xA;        console.error("Error uploading file: ", err);&#xA;        throw new Error(&#x27;Failed to upload file to S3&#x27;);&#xA;    }&#xA;}&#xA;&#xA;function parseDuration(durationStr) {&#xA;    const parts = durationStr.split(&#x27;:&#x27;);&#xA;    return parseInt(parts[0]) * 3600 &#x2B; parseInt(parts[1]) * 60 &#x2B; parseFloat(parts[2]);&#xA;}&#xA;&#xA;export async function handler(event) {&#xA;    const videoBucket = "video-interaction-content";&#xA;    const videoKey = event.videoKey;&#xA;    const audioBucket = "audio-call-recordings";&#xA;    const audioKey = event.audioKey;&#xA;    const outputBucket = "synched-audio-video";&#xA;    const outputKey = `combined_${basename(videoKey, &#x27;.mp4&#x27;)}.mp4`;&#xA;&#xA;    const audioStartSeconds = new Date(event.audioStart).getTime() / 1000;&#xA;    const videoStartSeconds = new Date(event.videoStart).getTime() / 1000;&#xA;    const audioDurationSeconds = event.audioDuration / 1000;&#xA;    const timeDifference = audioStartSeconds - videoStartSeconds;&#xA;&#xA;    try {&#xA;        const videoPath = `/tmp/${basename(videoKey)}`;&#xA;        const audioPath = `/tmp/${basename(audioKey)}`;&#xA;        await downloadFileFromS3(videoBucket, videoKey, videoPath);&#xA;        await downloadFileFromS3(audioBucket, audioKey, audioPath);&#xA;&#xA;        //Initialize file list with video&#xA;        let filelist = [`file &#x27;${videoPath}&#x27;`];&#xA;        let totalVideoDuration = 0; // Initialize total video duration&#xA;&#xA;        // Create first blank video if needed&#xA;        if (timeDifference &lt; 0) {&#xA;            const blankVideoDuration = Math.abs(timeDifference);&#xA;            const blankVideoPath = `/tmp/blank_video.mp4`;&#xA;            await execAsync(`/opt/bin/ffmpeg -f lavfi -i color=c=black:s=1280x720:r=25 -c:v libx264 -t ${blankVideoDuration} ${blankVideoPath}`);&#xA;            //Add first blank video first in file list&#xA;            filelist.unshift(`file &#x27;${blankVideoPath}&#x27;`);&#xA;            totalVideoDuration &#x2B;= blankVideoDuration;&#xA;            console.log(`First blank video created with duration: ${blankVideoDuration} seconds`);&#xA;        }&#xA;        &#xA;        const videoInfo = await execAsync(`/opt/bin/ffmpeg -i ${videoPath} -f null -`);&#xA;        const videoDurationMatch = videoInfo.stderr.match(/Duration: ([\d:.]&#x2B;)/);&#xA;        const videoDuration = videoDurationMatch ? parseDuration(videoDurationMatch[1]) : 0;&#xA;        totalVideoDuration &#x2B;= videoDuration;&#xA;&#xA;        // Calculate additional blank video duration&#xA;        const additionalBlankVideoDuration = audioDurationSeconds - totalVideoDuration;&#xA;        if (additionalBlankVideoDuration > 0) {&#xA;            const additionalBlankVideoPath = `/tmp/additional_blank_video.mp4`;&#xA;            await execAsync(`/opt/bin/ffmpeg -f lavfi -i color=c=black:s=1280x720:r=25 -c:v libx264 -t ${additionalBlankVideoDuration} ${additionalBlankVideoPath}`);&#xA;            //Add to the end of the file list&#xA;            filelist.push(`file &#x27;${additionalBlankVideoPath}&#x27;`);&#xA;            console.log(`Additional blank video created with duration: ${additionalBlankVideoDuration} seconds`);&#xA;        }&#xA;&#xA;        // Create and write the file list to disk&#xA;        const concatFilePath = &#x27;/tmp/filelist.txt&#x27;;&#xA;        await fsPromises.writeFile(&#x27;/tmp/filelist.txt&#x27;, filelist.join(&#x27;\n&#x27;));&#xA;&#xA;        const extendedVideoPath = `/tmp/extended_${basename(videoKey)}`;&#xA;        //await execAsync(`/opt/bin/ffmpeg -f concat -safe 0 -i /tmp/filelist.txt -c copy ${extendedVideoPath}`);&#xA;        &#xA;        // Use -vsync vfr to adjust frame timing without full re-encoding&#xA;        await execAsync(`/opt/bin/ffmpeg -f concat -safe 0 -i ${concatFilePath} -c copy -vsync vfr ${extendedVideoPath}`);&#xA;&#xA;        const outputPath = `/tmp/output_${basename(videoKey, &#x27;.mp4&#x27;)}.mp4`;&#xA;        //await execAsync(`/opt/bin/ffmpeg -i ${extendedVideoPath} -i ${audioPath} -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 192k -shortest ${outputPath}`);&#xA;&#xA;        await execAsync(`/opt/bin/ffmpeg -i ${extendedVideoPath} -i ${audioPath} -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 192k -shortest -r 25 ${outputPath}`);&#xA;        console.log(&#x27;Video and audio have been merged successfully&#x27;);&#xA;&#xA;        await uploadFileToS3(outputBucket, outputKey, outputPath);&#xA;        console.log(&#x27;File upload complete.&#x27;);&#xA;&#xA;        return { statusCode: 200, body: JSON.stringify(&#x27;Video and audio have been merged successfully.&#x27;) };&#xA;    } catch (error) {&#xA;        console.error(&#x27;Error in Lambda function:&#x27;, error);&#xA;        return { statusCode: 500, body: JSON.stringify(&#x27;Failed to process video and audio.&#x27;) };&#xA;    }&#xA;}&#xA;

    &#xA;

    Attempts :&#xA;I've tried re-encoding the concatenated file but the lambda function times out. I hoped that by creating blank video with a 25fps and all the other specs from the original mp4, I wouldn't have to re-encode the concatenated file. Obviously something is wrong, though. In the commented out code you can see I tried specifying 25 or not, and also tried -vsync and no -vsync. I'm new to FFmpeg so all tips are appreciated !

    &#xA;

  • What permission ffmpeg-static need in AWS Lambda ?

    17 février 2023, par János

    I have this code. It download a image, made a video from it and upload it to S3. It runs on Lambda. Added packages, intalled, zipped, uploaded.

    &#xA;

    npm install --production&#xA;zip -r my-lambda-function.zip ./&#xA;

    &#xA;

    But get an error code 126

    &#xA;

    2023-02-17T09:27:55.236Z    5c845bb6-02c1-41b0-8759-4459591b57b0    INFO    Error: ffmpeg exited with code 126&#xA;    at ChildProcess.<anonymous> (/var/task/node_modules/fluent-ffmpeg/lib/processor.js:182:22)&#xA;    at ChildProcess.emit (node:events:513:28)&#xA;    at ChildProcess._handle.onexit (node:internal/child_process:291:12)&#xA;2023-02-17T09:27:55.236Z 5c845bb6-02c1-41b0-8759-4459591b57b0 INFO Error: ffmpeg exited with code 126 at ChildProcess.<anonymous> (/var/task/node_modules/fluent-ffmpeg/lib/processor.js:182:22) at ChildProcess.emit (node:events:513:28) at ChildProcess._handle.onexit (node:internal/child_process:291:12)&#xA;</anonymous></anonymous>

    &#xA;

    Do I need to set a specific premission for ffmpeg ?

    &#xA;

    import { PutObjectCommand, S3Client } from &#x27;@aws-sdk/client-s3&#x27;&#xA;import { fromNodeProviderChain } from &#x27;@aws-sdk/credential-providers&#x27;&#xA;import axios from &#x27;axios&#x27;&#xA;import pathToFfmpeg from &#x27;ffmpeg-static&#x27;&#xA;import ffmpeg from &#x27;fluent-ffmpeg&#x27;&#xA;import fs from &#x27;fs&#x27;&#xA;ffmpeg.setFfmpegPath(pathToFfmpeg)&#xA;const credentials = fromNodeProviderChain({&#xA;    clientConfig: {&#xA;        region: &#x27;eu-central-1&#x27;,&#xA;    },&#xA;})&#xA;const client = new S3Client({ credentials })&#xA;&#xA;export const handler = async (event, context) => {&#xA;    try {&#xA;        let body&#xA;        let statusCode = 200&#xA;        const query = event?.queryStringParameters&#xA;        if (!query?.imgId &amp;&amp; !query?.video1Id &amp;&amp; !query?.video2Id) {&#xA;            return&#xA;        }&#xA;&#xA;        const imgId = query?.imgId&#xA;        const video1Id = query?.video1Id&#xA;        const video2Id = query?.video2Id&#xA;        console.log(&#xA;            `Parameters received, imgId: ${imgId}, video1Id: ${video1Id}, video2Id: ${video2Id}`&#xA;        )&#xA;        const imgURL = getFileURL(imgId)&#xA;        const video1URL = getFileURL(`${video1Id}.mp4`)&#xA;        const video2URL = getFileURL(`${video2Id}.mp4`)&#xA;        const imagePath = `/tmp/${imgId}`&#xA;        const video1Path = `/tmp/${video1Id}.mp4`&#xA;        const video2Path = `/tmp/${video2Id}.mp4`&#xA;        const outputPath = `/tmp/${imgId}.mp4`&#xA;        await Promise.all([&#xA;            downloadFile(imgURL, imagePath),&#xA;            downloadFile(video1URL, video1Path),&#xA;            downloadFile(video2URL, video2Path),&#xA;        ])&#xA;        await new Promise((resolve, reject) => {&#xA;            console.log(&#x27;Input files downloaded&#x27;)&#xA;            ffmpeg()&#xA;                .input(imagePath)&#xA;                .inputFormat(&#x27;image2&#x27;)&#xA;                .inputFPS(30)&#xA;                .loop(1)&#xA;                .size(&#x27;1080x1080&#x27;)&#xA;                .videoCodec(&#x27;libx264&#x27;)&#xA;                .format(&#x27;mp4&#x27;)&#xA;                .outputOptions([&#xA;                    &#x27;-tune animation&#x27;,&#xA;                    &#x27;-pix_fmt yuv420p&#x27;,&#xA;                    &#x27;-profile:v baseline&#x27;,&#xA;                    &#x27;-level 3.0&#x27;,&#xA;                    &#x27;-preset medium&#x27;,&#xA;                    &#x27;-crf 23&#x27;,&#xA;                    &#x27;-movflags &#x2B;faststart&#x27;,&#xA;                    &#x27;-y&#x27;,&#xA;                ])&#xA;                .output(outputPath)&#xA;                .on(&#x27;end&#x27;, () => {&#xA;                    console.log(&#x27;Output file generated&#x27;)&#xA;                    resolve()&#xA;                })&#xA;                .on(&#x27;error&#x27;, (e) => {&#xA;                    console.log(e)&#xA;                    reject()&#xA;                })&#xA;                .run()&#xA;            &#xA;        })&#xA;        await uploadFile(outputPath, imgId &#x2B; &#x27;.mp4&#x27;)&#xA;            .then((url) => {&#xA;                body = JSON.stringify({&#xA;                    url,&#xA;                })&#xA;            })&#xA;            .catch((error) => {&#xA;                console.error(error)&#xA;                statusCode = 400&#xA;                body = error?.message ?? error&#xA;            })&#xA;        console.log(`File uploaded to S3`)&#xA;        const headers = {&#xA;            &#x27;Content-Type&#x27;: &#x27;application/json&#x27;,&#xA;            &#x27;Access-Control-Allow-Headers&#x27;: &#x27;Content-Type&#x27;,&#xA;            &#x27;Access-Control-Allow-Origin&#x27;: &#x27;https://tikex.com, https://borespiac.hu&#x27;,&#xA;            &#x27;Access-Control-Allow-Methods&#x27;: &#x27;GET&#x27;,&#xA;        }&#xA;        return {&#xA;            statusCode,&#xA;            body,&#xA;            headers,&#xA;        }&#xA;    } catch (error) {&#xA;        console.error(error)&#xA;        return {&#xA;            statusCode: 500,&#xA;            body: JSON.stringify(&#x27;Error fetching data&#x27;),&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;const downloadFile = async (url, path) => {&#xA;    try {&#xA;        console.log(`Download will start: ${url}`)&#xA;        const response = await axios(url, {&#xA;            responseType: &#x27;stream&#x27;,&#xA;        })&#xA;        if (response.status !== 200) {&#xA;            throw new Error(&#xA;                `Failed to download file, status code: ${response.status}`&#xA;            )&#xA;        }&#xA;        response.data&#xA;            .pipe(fs.createWriteStream(path))&#xA;            .on(&#x27;finish&#x27;, () => console.log(`File downloaded to ${path}`))&#xA;            .on(&#x27;error&#x27;, (e) => {&#xA;                throw new Error(`Failed to save file: ${e}`)&#xA;            })&#xA;    } catch (e) {&#xA;        console.error(`Error downloading file: ${e}`)&#xA;    }&#xA;}&#xA;const uploadFile = async (path, id) => {&#xA;    const buffer = fs.readFileSync(path)&#xA;    const params = {&#xA;        Bucket: &#x27;t44-post-cover&#x27;,&#xA;        ACL: &#x27;public-read&#x27;,&#xA;        Key: id,&#xA;        ContentType: &#x27;video/mp4&#x27;,&#xA;        Body: buffer,&#xA;    }&#xA;    await client.send(new PutObjectCommand(params))&#xA;    return getFileURL(id)&#xA;}&#xA;const getFileURL = (id) => {&#xA;    const bucket = &#x27;t44-post-cover&#x27;&#xA;    const url = `https://${bucket}.s3.eu-central-1.amazonaws.com/${id}`&#xA;    return url&#xA;}&#xA;

    &#xA;

    Added AWSLambdaBasicExecutionRole-16e770c8-05fa-4c42-9819-12c468cb5b49 permission, with policy :

    &#xA;

    {&#xA;    "Version": "2012-10-17",&#xA;    "Statement": [&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": "logs:CreateLogGroup",&#xA;            "Resource": "arn:aws:logs:eu-central-1:634617701827:*"&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "logs:CreateLogStream",&#xA;                "logs:PutLogEvents"&#xA;            ],&#xA;            "Resource": [&#xA;                "arn:aws:logs:eu-central-1:634617701827:log-group:/aws/lambda/promo-video-composer-2:*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "s3:GetObject",&#xA;                "s3:PutObject",&#xA;                "s3:ListBucket"&#xA;            ],&#xA;            "Resource": [&#xA;                "arn:aws:s3:::example-bucket",&#xA;                "arn:aws:s3:::example-bucket/*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "logs:CreateLogGroup",&#xA;                "logs:CreateLogStream",&#xA;                "logs:PutLogEvents"&#xA;            ],&#xA;            "Resource": [&#xA;                "arn:aws:logs:*:*:*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "ec2:DescribeNetworkInterfaces"&#xA;            ],&#xA;            "Resource": [&#xA;                "*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "sns:*"&#xA;            ],&#xA;            "Resource": [&#xA;                "*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "cloudwatch:*"&#xA;            ],&#xA;            "Resource": [&#xA;                "*"&#xA;            ]&#xA;        },&#xA;        {&#xA;            "Effect": "Allow",&#xA;            "Action": [&#xA;                "kms:Decrypt"&#xA;            ],&#xA;            "Resource": [&#xA;                "*"&#xA;            ]&#xA;        }&#xA;    ]&#xA;}&#xA;

    &#xA;

    What do I miss ?

    &#xA;

    janoskukoda@Janoss-MacBook-Pro promo-video-composer-2 % ls -l $(which ffmpeg)&#xA;lrwxr-xr-x  1 janoskukoda  admin  35 Feb 10 12:50 /opt/homebrew/bin/ffmpeg -> ../Cellar/ffmpeg/5.1.2_4/bin/ffmpeg&#xA;

    &#xA;