Fusionner Vidéo et Audio avec FFmpeg en Java

Ce guide détaille le processus d'intégration de fichiers vidéo et audio à l'aide de FFmpeg dans une application Java. Les versions récentes de FFmpeg ont introduit des modifications dans leurs commandes, nécessitant une approche mise à jour.

Configuration de FFmpeg

Téléchargez la dernière version de FFmpeg depuis le site officiel : http://ffmpeg.org/download.html. Après le téléchargement, extrayez les fichiers pour rendre l'exécutable accessible.

Méthode de Fusion Initiale (Ancienne Approche)

La commande FFmpeg pour fusionner une vidéo et un fichier audio dans les anciennes versions était la suivante :

ffmpeg.exe -i video_originale.mp4 -i musique_bg.mp3 -t 7 -y video_finale.mp4

Voici une implémentation Java pour cette commande :


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class FusionVideoAudioV1 {

    private final String ffmpegExecutablePath;

    public FusionVideoAudioV1(String ffmpegExecutablePath) {
        this.ffmpegExecutablePath = ffmpegExecutablePath;
    }

    public void creerVideoAvecAudio(String cheminVideoEntree, String cheminAudioEntree,
                                   double dureeSecondes, String cheminVideoSortie) throws Exception {
        List<string> commande = new ArrayList<>();
        commande.add(ffmpegExecutablePath);
        commande.add("-i");
        commande.add(cheminVideoEntree);
        commande.add("-i");
        commande.add(cheminAudioEntree);
        commande.add("-t");
        commande.add(String.valueOf(dureeSecondes));
        commande.add("-y"); // Écrase le fichier de sortie s'il existe
        commande.add(cheminVideoSortie);

        ProcessBuilder constructeurProcess = new ProcessBuilder(commande);
        Process processus = constructeurProcess.start();

        // Lire la sortie d'erreur pour le débogage
        try (InputStream fluxErreur = processus.getErrorStream();
             InputStreamReader lecteurErreur = new InputStreamReader(fluxErreur);
             BufferedReader lecteurBuffer = new BufferedReader(lecteurErreur)) {
            String ligne;
            while ((ligne = lecteurBuffer.readLine()) != null) {
                // Optionnel : journaliser ou traiter les messages d'erreur
            }
        }
    }

    public static void main(String[] args) {
        FusionVideoAudioV1 ffmpeg = new FusionVideoAudioV1("C:\\ffmpeg\\bin\\ffmpeg.exe");
        try {
            ffmpeg.creerVideoAvecAudio("C:\\video_source.mp4", "C:\\musique_bg.mp3", 7.1, "C:\\video_generee_java.mp4");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
</string>

Méthode de Fusion Mises à Jour (Nouvelle Approche)

Les versions plus récentes de FFmpeg peuvent nécessiter une approche en deux étapes : d'abord, extraire le flux audio du fichier vidéo original, puis fusionner cette vidéo sans audio avec le nouveau fichier audio.

Étape 1 : Extraire l'audio de la vidéo

ffmpeg.exe -i video_originale.mp4 -vcodec copy -an video_sans_audio.mp4

Étape 2 : Fusionner la vidéo sans audio avec le nouveau fichier audio

ffmpeg.exe -i video_sans_audio.mp4 -i musique_ajout.mp3 -t 10 -y resultat_final.mp4

Voici l'implémentation Java correspondante :


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class FusionVideoAudioV2 {

    private final String ffmpegExecutablePath;

    public FusionVideoAudioV2(String ffmpegExecutablePath) {
        this.ffmpegExecutablePath = ffmpegExecutablePath;
    }

    public void convertirEtFusionner(String cheminVideoEntree, String cheminVideoTemporaire,
                                     String cheminAudioEntree, double dureeSecondes,
                                     String cheminVideoSortie) throws Exception {

        // Étape 1 : Supprimer l'audio de la vidéo source
        List<string> commandeExtractionAudio = new ArrayList<>();
        commandeExtractionAudio.add(ffmpegExecutablePath);
        commandeExtractionAudio.add("-i");
        commandeExtractionAudio.add(cheminVideoEntree);
        commandeExtractionAudio.add("-vcodec"); // Copier le flux vidéo sans ré-encodage
        commandeExtractionAudio.add("copy");
        commandeExtractionAudio.add("-an"); // Supprimer le flux audio
        commandeExtractionAudio.add(cheminVideoTemporaire);
        exExcuterCommande(commandeExtractionAudio);

        // Étape 2 : Fusionner la vidéo sans audio avec le nouveau fichier audio
        List<string> commandeFusion = new ArrayList<>();
        commandeFusion.add(ffmpegExecutablePath);
        commandeFusion.add("-i");
        commandeFusion.add(cheminVideoTemporaire);
        commandeFusion.add("-i");
        commandeFusion.add(cheminAudioEntree);
        commandeFusion.add("-t"); // Durée de la vidéo de sortie
        commandeFusion.add(String.valueOf(dureeSecondes));
        commandeFusion.add("-y"); // Écrase le fichier de sortie s'il existe
        commandeFusion.add(cheminVideoSortie);
        exExcuterCommande(commandeFusion);
    }

    /**
     * Exécute une commande FFmpeg et gère le flux de sortie d'erreur.
     * @param commande La liste des arguments de la commande.
     */
    private void exExcuterCommande(List<string> commande) {
        ProcessBuilder constructeurProcess = new ProcessBuilder(commande);
        Process processus;
        InputStream fluxErreur = null;
        InputStreamReader lecteurErreur = null;
        BufferedReader lecteurBuffer = null;
        try {
            processus = constructeurProcess.start();
            fluxErreur = processus.getErrorStream();
            lecteurErreur = new InputStreamReader(fluxErreur);
            lecteurBuffer = new BufferedReader(lecteurErreur);

            String ligne;
            while ((ligne = lecteurBuffer.readLine()) != null) {
                // Optionnel : journaliser ou traiter les messages
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (lecteurBuffer != null) lecteurBuffer.close();
                if (lecteurErreur != null) lecteurErreur.close();
                if (fluxErreur != null) fluxErreur.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        FusionVideoAudioV2 ffmpeg = new FusionVideoAudioV2("C:\\ffmpeg\\bin\\ffmpeg.exe");
        try {
            // Assurez-vous que les chemins correspondent à votre configuration
            ffmpeg.convertirEtFusionner("D:\\video_source.mp4", "D:\\video_temp.mp4", "D:\\musique_ajout.mp3", 7.1, "D:\\video_generee_java.mp4");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
</string></string></string>

Si la génération de la vidéo échoue, copiez la commande FFmpeg générée par le code et exécutez-la directement dans votre terminal. Cela vous aidera à identifier les erreurs spécifiques.

Étiquettes: FFmpeg Java video editing audio integration media processing

Publié le 31 août à 17h52