
Recherche avancée
Autres articles (111)
-
Le profil des utilisateurs
12 avril 2011, parChaque utilisateur dispose d’une page de profil lui permettant de modifier ses informations personnelle. Dans le menu de haut de page par défaut, un élément de menu est automatiquement créé à l’initialisation de MediaSPIP, visible uniquement si le visiteur est identifié sur le site.
L’utilisateur a accès à la modification de profil depuis sa page auteur, un lien dans la navigation "Modifier votre profil" est (...) -
Configurer la prise en compte des langues
15 novembre 2010, parAccéder à la configuration et ajouter des langues prises en compte
Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...) -
XMP PHP
13 mai 2011, parDixit Wikipedia, XMP signifie :
Extensible Metadata Platform ou XMP est un format de métadonnées basé sur XML utilisé dans les applications PDF, de photographie et de graphisme. Il a été lancé par Adobe Systems en avril 2001 en étant intégré à la version 5.0 d’Adobe Acrobat.
Étant basé sur XML, il gère un ensemble de tags dynamiques pour l’utilisation dans le cadre du Web sémantique.
XMP permet d’enregistrer sous forme d’un document XML des informations relatives à un fichier : titre, auteur, historique (...)
Sur d’autres sites (9816)
-
FFMPEG Concatenating videos with same 25fps results in output file with 3.554fps
5 juin 2024, par Kendra BroomI 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 !


-
Inserting clips into mp4 via ffmpeg
15 septembre 2024, par lfganI 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 :


- 

- Convert "myfile.mp3" to "music.mp4" with image (works)
- Add "intro.mp4" to the start of "music.mp4" and "Output.mp4" to the end (works)
- 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)
- Put all clips in order (unknown, probably works but part 2 and 3 wont generate so it cannot get to that step.)










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



-
avcodec/vvcdec : ensure every CTU belongs to a slice
23 novembre 2024, par Nuo Miavcodec/vvcdec : ensure every CTU belongs to a slice
According to section 6.3.3 "Spatial or component-wise partitionings,"
CTUs should fully cover slices with no overlaps, gaps, or additions.
No overlaps are ensured by task_init_parse.
No gaps and no additions are ensured by this patch.Co-authored-by : Frank Plowman <post@frankplowman.com>