Recherche avancée

Médias (16)

Mot : - Tags -/mp3

Autres articles (46)

  • Contribute to a better visual interface

    13 avril 2011

    MediaSPIP is based on a system of themes and templates. Templates define the placement of information on the page, and can be adapted to a wide range of uses. Themes define the overall graphic appearance of the site.
    Anyone can submit a new graphic theme or template and make it available to the MediaSPIP community.

  • Ajouter notes et légendes aux images

    7 février 2011, par

    Pour pouvoir ajouter notes et légendes aux images, la première étape est d’installer le plugin "Légendes".
    Une fois le plugin activé, vous pouvez le configurer dans l’espace de configuration afin de modifier les droits de création / modification et de suppression des notes. Par défaut seuls les administrateurs du site peuvent ajouter des notes aux images.
    Modification lors de l’ajout d’un média
    Lors de l’ajout d’un média de type "image" un nouveau bouton apparait au dessus de la prévisualisation (...)

  • Submit bugs and patches

    13 avril 2011

    Unfortunately a software is never perfect.
    If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
    If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
    You may also (...)

Sur d’autres sites (9199)

  • Inserting clips into mp4 via ffmpeg

    15 septembre 2024, par lfgan

    I am looking to create mp4 files by combining multiple static mp4s and mp3s.
I have a script already to convert mp3 to mp4 and using the album art as a static background image, and inserting the intro.
What I am having problems with is that it cannot concatenate the videos reliably, or at all for that matter.

    


    This is the code that I currently have, it is ChatGPT, however I gave up as it seemed like it was just running in circles.

    


    setlocal

:: Set variables
set "mp3file=myfile.mp3"
set "coverart=extracted_cover.jpg"
set "outputfile=music.mp4"
set "introfile=intro.mp4"
set "outputendfile=Outro.mp4"
set "wowfile=Wow!.mp4"

:: Step 1: Extract cover art from MP3
ffmpeg -i "%mp3file%" -an -vcodec copy "%coverart%"
if %errorlevel% neq 0 (
    echo Error: Failed to extract cover art from MP3 file.
    exit /b 1
)

:: Step 2: Convert MP3 to MP4 using the extracted cover art
ffmpeg -loop 1 -i "%coverart%" -i "%mp3file%" -c:v libx264 -tune stillimage -c:a aac -b:a 192k -shortest "%outputfile%"
if %errorlevel% neq 0 (
    echo Error: Conversion from MP3 to MP4 failed.
    exit /b 1
)

:: Step 3: Randomly generate two positions for Wow!.mp4 insertions
:: Random positions will be between 10 and 50 seconds
set /a "pos1=%random% %% 40 + 10"
set /a "pos2=%random% %% 40 + 10"

:: Ensure pos1 and pos2 are different
if %pos1% EQU %pos2% (
    set /a "pos2=%pos1%+10"
)

:: Print positions for debugging
echo Random insertion positions:
echo Position 1: %pos1%
echo Position 2: %pos2%

:: Step 4: Split the music mp4 into parts at the random positions
:: Part 1: From the beginning to pos1
ffmpeg -i "%outputfile%" -c copy -ss 0 -to %pos1% -y "part1.mp4"
if not exist "part1.mp4" (
    echo Error: Failed to create part1.mp4
    exit /b 1
)

:: Part 2: From pos1 to pos2
ffmpeg -i "%outputfile%" -c copy -ss %pos1% -to %pos2% -y "part2.mp4"
if not exist "part2.mp4" (
    echo Error: Failed to create part2.mp4
    exit /b 1
)

:: Part 3: From pos2 to the end
ffmpeg -i "%outputfile%" -c copy -ss %pos2% -y "part3.mp4"
if not exist "part3.mp4" (
    echo Error: Failed to create part3.mp4
    exit /b 1
)

:: Step 5: Concatenate the files in the required order
(
    echo file 'intro.mp4'
    echo file 'part1.mp4'
    echo file 'Wow!.mp4'
    echo file 'part2.mp4'
    echo file 'Wow!.mp4'
    echo file 'part3.mp4'
    echo file 'Outro.mp4'
) > concat_list.txt

ffmpeg -f concat -safe 0 -i concat_list.txt -c copy final_output.mp4
if %errorlevel% neq 0 (
    echo Error: Failed to concatenate the video files.
    exit /b 1
)

:: Cleanup
del part1.mp4 part2.mp4 part3.mp4 concat_list.txt "%coverart%"

echo Done! The final video is saved as final_output.mp4


    


    exactly what it is supposed to do :

    


      

    1. Convert "myfile.mp3" to "music.mp4" with image (works)
    2. 


    3. Add "intro.mp4" to the start of "music.mp4" and "Output.mp4" to the end (works)
    4. 


    5. Split "music.mp4" into 3 parts, randomly, at a minimum 10s after intro.mp4 and 10s before Outro.mp4 (can for some reason only create part 1)
    6. 


    7. Put all clips in order (unknown, probably works but part 2 and 3 wont generate so it cannot get to that step.)
    8. 


    


    Edit :
I forgot to add the error message that I am getting. Here it is :

    


    [out#0 @ 000002e024a6ed00] -to value smaller than -ss; aborting.
Error opening output file part2.mp4.
Error opening output files: Invalid argument
Error: Failed to create part2.mp4


    


  • 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.

    


    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.

    


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

    


    Audio :
wav, 13kbps, aac (LC), 6:28 duration

    


    Video :
mp4, 1280x720 resolution, 25 frame rate, h264 codec, 3:27 duration

    


    Goal :
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.

    


    Actual Result :
An mp4 file with 3.554 frame rate and 10:06 duration.

    


    import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
import { createWriteStream, createReadStream, promises as fsPromises } from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';
import { basename } from 'path';

const execAsync = promisify(exec);

const s3 = new S3Client({ region: 'us-east-1' });

async function downloadFileFromS3(bucket, key, downloadPath) {
    const getObjectParams = { Bucket: bucket, Key: key };
    const command = new GetObjectCommand(getObjectParams);
    const { Body } = await s3.send(command);
    return new Promise((resolve, reject) => {
        const fileStream = createWriteStream(downloadPath);
        Body.pipe(fileStream);
        Body.on('error', reject);
        fileStream.on('finish', resolve);
    });
}

async function uploadFileToS3(bucket, key, filePath) {
    const fileStream = createReadStream(filePath);
    const uploadParams = { Bucket: bucket, Key: key, Body: fileStream };
    try {
        await s3.send(new PutObjectCommand(uploadParams));
        console.log(`File uploaded successfully to ${bucket}/${key}`);
    } catch (err) {
        console.error("Error uploading file: ", err);
        throw new Error('Failed to upload file to S3');
    }
}

function parseDuration(durationStr) {
    const parts = durationStr.split(':');
    return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseFloat(parts[2]);
}

export async function handler(event) {
    const videoBucket = "video-interaction-content";
    const videoKey = event.videoKey;
    const audioBucket = "audio-call-recordings";
    const audioKey = event.audioKey;
    const outputBucket = "synched-audio-video";
    const outputKey = `combined_${basename(videoKey, '.mp4')}.mp4`;

    const audioStartSeconds = new Date(event.audioStart).getTime() / 1000;
    const videoStartSeconds = new Date(event.videoStart).getTime() / 1000;
    const audioDurationSeconds = event.audioDuration / 1000;
    const timeDifference = audioStartSeconds - videoStartSeconds;

    try {
        const videoPath = `/tmp/${basename(videoKey)}`;
        const audioPath = `/tmp/${basename(audioKey)}`;
        await downloadFileFromS3(videoBucket, videoKey, videoPath);
        await downloadFileFromS3(audioBucket, audioKey, audioPath);

        //Initialize file list with video
        let filelist = [`file '${videoPath}'`];
        let totalVideoDuration = 0; // Initialize total video duration

        // Create first blank video if needed
        if (timeDifference < 0) {
            const blankVideoDuration = Math.abs(timeDifference);
            const blankVideoPath = `/tmp/blank_video.mp4`;
            await execAsync(`/opt/bin/ffmpeg -f lavfi -i color=c=black:s=1280x720:r=25 -c:v libx264 -t ${blankVideoDuration} ${blankVideoPath}`);
            //Add first blank video first in file list
            filelist.unshift(`file '${blankVideoPath}'`);
            totalVideoDuration += blankVideoDuration;
            console.log(`First blank video created with duration: ${blankVideoDuration} seconds`);
        }
        
        const videoInfo = await execAsync(`/opt/bin/ffmpeg -i ${videoPath} -f null -`);
        const videoDurationMatch = videoInfo.stderr.match(/Duration: ([\d:.]+)/);
        const videoDuration = videoDurationMatch ? parseDuration(videoDurationMatch[1]) : 0;
        totalVideoDuration += videoDuration;

        // Calculate additional blank video duration
        const additionalBlankVideoDuration = audioDurationSeconds - totalVideoDuration;
        if (additionalBlankVideoDuration > 0) {
            const additionalBlankVideoPath = `/tmp/additional_blank_video.mp4`;
            await execAsync(`/opt/bin/ffmpeg -f lavfi -i color=c=black:s=1280x720:r=25 -c:v libx264 -t ${additionalBlankVideoDuration} ${additionalBlankVideoPath}`);
            //Add to the end of the file list
            filelist.push(`file '${additionalBlankVideoPath}'`);
            console.log(`Additional blank video created with duration: ${additionalBlankVideoDuration} seconds`);
        }

        // Create and write the file list to disk
        const concatFilePath = '/tmp/filelist.txt';
        await fsPromises.writeFile('/tmp/filelist.txt', filelist.join('\n'));

        const extendedVideoPath = `/tmp/extended_${basename(videoKey)}`;
        //await execAsync(`/opt/bin/ffmpeg -f concat -safe 0 -i /tmp/filelist.txt -c copy ${extendedVideoPath}`);
        
        // Use -vsync vfr to adjust frame timing without full re-encoding
        await execAsync(`/opt/bin/ffmpeg -f concat -safe 0 -i ${concatFilePath} -c copy -vsync vfr ${extendedVideoPath}`);

        const outputPath = `/tmp/output_${basename(videoKey, '.mp4')}.mp4`;
        //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}`);

        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}`);
        console.log('Video and audio have been merged successfully');

        await uploadFileToS3(outputBucket, outputKey, outputPath);
        console.log('File upload complete.');

        return { statusCode: 200, body: JSON.stringify('Video and audio have been merged successfully.') };
    } catch (error) {
        console.error('Error in Lambda function:', error);
        return { statusCode: 500, body: JSON.stringify('Failed to process video and audio.') };
    }
}


    


    Attempts :
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 !

    


  • lavc/internal : document the precise meaning of AVCodecInternal.draining

    3 avril 2024, par Anton Khirnov
    lavc/internal : document the precise meaning of AVCodecInternal.draining
    

    Also, set draining=1 in case a bitstream filter returns an
    internally-triggered EOF. While no bitstream filters currently inserted
    by decoders will do that, that may change in the future and it is better
    to cover this case.

    • [DH] libavcodec/decode.c
    • [DH] libavcodec/internal.h