Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 16/08/2008, à 23:40

Aldian

Programme pour faire de la conversion en masse avec ffmpeg.

Avant propos:
Bien qu'ayant déjà plus d'un an d'ancienneté sous Ubuntu, je suis encore novice sur beaucoup de points. Alors je ne prétends pas utiliser ici la solution la plus simple, mais au moins ça marche. Les remarques visant à permettre l'amélioration sont les bienvenues.


Problématique:
J'ai sur mon ordinateur tout un tas de fichiers multimédias qui sont sous un certain format pour certaines applications et dont j'aurais besoin sous un autre format pour d'autres applications. Je sais convertir les fichiers en ligne de commande grâce à ffmpeg, mais je n'ai pas envie de taper la commande 200 fois pour 200 fichiers différents en changeant à chaque fois les noms des fichiers dans la commande. Sachant qu'en plus pour corser les choses, nombre de noms de fichiers contiennent des espaces et même des parenthèses.


Solution:
J'ai écrit un programme en java qui génère un petit script shell avec toutes les commandes à l'intérieur. Un vieux routard du script shell aurait sans doute pu écrire un script qui fait tout, malheureusement, je n'y connais personnellement pas grand chose en particulier dés qu'on commence à utiliser des awk et des pipe. Donc j'ai fait avec ce que je connaissais: le java, et encore j'ai eu deux ou trois petites difficultés que j'ai contournées comme j'ai pu.


Tutoriel:

1) prérequis:
*Avoir installé le paquet ffmpeg en le recompilant si nécessaire avec tous les formats que l'ont veut. Voir la page ffmpeg de la documentation.
*Si le chemin d'installation de ffmpeg n'était pas dans le PATH, l'avoir rajouté.
*Avoir installé le paquet gcj


2) le programme java:
Ouvrez un éditeur de texte et copiez/collez-y le code suivant. Puis enregistrez sous le nom Massffmpeg.java

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Programme Massffmpeg. Ce programme est délivré sous la license s'appliquant au forum d'Ubuntu.fr
 * Date de MAJ 16/08/2008
 * @author aldian
 */
public class Massffmpeg {
    String [] Originalcommand;
    String option1="";
    String typeSource="";
    String option2="";
    String typeDest="";
    String option3="";
    
    public Massffmpeg (String [] args)
    {
        Originalcommand=args;
        
        int i;
        for (i=0;i<args.length && args[i].indexOf("typeSource")==-1;i++)
            option1+=args[i]+" ";
        
        typeSource=args[++i];
        
        for(i++;i<args.length && args[i].indexOf("typeDest")==-1;i++)
            option2+=args[i]+" ";
        
        typeDest=args[++i];
        
        for(i++;i<args.length;i++)
            option3+=args[i]+" ";
    }
    
    
    public static void main(String [] args)
    {
        //String [] args={"-ab","128k","-i","typeSource","flv","typeDest","mp3"};
        Massffmpeg m=new Massffmpeg(args);
        String [] nameFileArray=m.getNameFileArray();
        String [] commandArray=m.makeCommandArray(nameFileArray);
        try {
            //m.convert(commandArray, nameFileArray);
            m.writeScript(commandArray);
        } catch (IOException iOException) {
            iOException.printStackTrace();
            /*} catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();*/
        }
    }
    
    public String [] getNameFileArray()
    {
        File tmp=new File("tmp");
        String path=tmp.getAbsolutePath();
        //System.out.println("nom du file: "+tmp.getName());
        //System.out.println("file absolute path: "+path);
        path=path.substring(0, path.length()-4);
        //System.out.println("dirctory absolute path: "+path);
        if (tmp.exists())
            tmp.delete();
        File dir=new File(path);

        
        File [] listFiles=dir.listFiles();
        
        
        int i,nbfile;
        for(i=0,nbfile=0;i<listFiles.length;i++)
            if(listFiles[i].getName().indexOf("."+typeSource)!=-1)
                nbfile++;
        
        int c;
        String [] nameFileArray=new String[nbfile];
        for(i=0,c=0;i<listFiles.length;i++)
            if(listFiles[i].getName().indexOf("."+typeSource)!=-1)
                nameFileArray[c++]=listFiles[i].getName();
            
        return nameFileArray;
    }
    
    public String [] makeCommandArray(String [] nameFileArray)
    {
        String [] commandArray=new String[nameFileArray.length];
        String nameWithoutExtension;
        for(int i=0;i<nameFileArray.length;i++)
        {
            nameWithoutExtension=nameFileArray[i].substring(0, nameFileArray[i].indexOf("."));
            nameWithoutExtension=addBackslashBeforeBlanks(nameWithoutExtension);
            commandArray[i]=option1+" "+nameWithoutExtension+"."+typeSource+" "+option2+" "+nameWithoutExtension+"."+typeDest+" "+option3;
        }
    return commandArray;
    }
    
    public void convert(String [] commandArray, String [] nameFileArray) throws IOException, InterruptedException
    {
         System.out. println(" ");
         System.out. println("*************** Massffmpeg ***********");
         System.out. println(" ");
         int i;
         Process p;
         Runtime runtime = Runtime.getRuntime();
         for(i=0;i<commandArray.length;i++)
         {
             System.out. println(" ");
             System.out. println("preparing conversion of file "+nameFileArray[i]+" to format "+typeDest+":");
             System.out. println("excuting command <"+"ffmpeg "+commandArray[i]+">");
             p=runtime.exec("ffmpeg "+commandArray[i]);
             p.waitFor();
             System.out. println("*********** finished ");
         }
    }
    
    public void writeScript(String [] commandArray) throws IOException
    {
        BufferedWriter bw  = new BufferedWriter(new FileWriter("ffmpeg_"+typeSource+"_to_"+typeDest+"_ConversionScript.sh"));
        bw.write("#!/bin/bash"+"\n");
        bw.write("# "+"\n");
        bw.write("# name: "+"ffmpeg_"+typeSource+"_to_"+typeDest+"_ConversionScript.sh"+"\n");
        bw.write("# input format: "+typeSource+"\n");
        bw.write("# output format: "+typeDest+"\n");
        bw.write("# "+"\n");
        for(int i=0;i<commandArray.length;i++)
            bw.write("ffmpeg "+commandArray[i]+"\n");
        bw.write("echo \"finished\"");
        bw.close();
    }
    
    public static String addBackslashBeforeBlanks(String s)
    {
        String rep="";
        int indexPrecBlank=0;
        for(int i=0;i<s.length();i++)
            if(s.charAt(i)==' ' || s.charAt(i)=='(' || s.charAt(i)==')' || s.charAt(i)=='\'')
            {
                rep+=s.substring(indexPrecBlank, i)+"\\";
                indexPrecBlank=i;
            }
        rep+=s.substring(indexPrecBlank);
        return rep;
    }

}

Ouvrez un terminal, placez vous dans le dosier où vous avez enregistré le fichier et tapez:

javac Massffmpeg.java

Ce qui a pour effet de compiler le programme et de générer un fichier nommé Massffmpeg.clas
Déplacez ce fichier dans le répertoire où se trouvent les fichiers que vous désirez convertir.



3) Utilisation:
Une commande standard d'utilisation de fmpeg serait

ffmpeg OPTIONS1 nom_fichier_source OPTIONS2 nom_fichier_dest OPTIONS3

La commande qui va vous permettre de lancer la conversion de mass est la suivante:

java Massffmpeg OPTIONS1 typeSource FORMAT_SOURCE OPTIONS2 typeDest FORMAT_DESTINATION OPTIONS3

Bien entendu, vous pouvez omettre les options 1 ou 2 ou 3 si vous n'avez rien à spécifier.
Un script dont le nom sera de type ffmpeg_FORMAT_SOURCE_to_FORMAT_DESTINATION_ConversionScript.sh a été généré. Vous devez tout d'abord le rendre exécutable, avant de pouvoir l'exécuter en tapant successivement:

chmod +x NOM_DU_SCRIPT
./NOM_DU_SCRIPT

Exemple:
Vous avez plusieurs fichiers de format flv dont vous souhaitez extraire la musique au format mp3.

préparation du script:

aldian@ubuntu:~/TEMP$ ll
total 20280
-rwxrwxrwx 1 aldian aldian 3544962 2008-08-14 20:21 artiste1 - titre1.flv
-rwxrwxrwx 1 aldian aldian 7865420 2008-08-14 19:30 artiste2 - titre2[HQ].flv
-rwxrwxrwx 1 aldian aldian 9305817 2008-08-14 22:49 artiste3 - titre3 (techno Remix).flv
-rw-r--r-- 1 aldian aldian    3872 2008-08-16 22:35 Massffmpeg.class
aldian@ubuntu:~/TEMP$ java Massffmpeg -ab 128k -i typeSource flv typeDest mp3
aldian@ubuntu:~/TEMP$ ll
total 20284
-rwxrwxrwx 1 aldian aldian 3544962 2008-08-14 20:21 artiste1 - titre1.flv
-rwxrwxrwx 1 aldian aldian 7865420 2008-08-14 19:30 artiste2 - titre2[HQ].flv
-rwxrwxrwx 1 aldian aldian 9305817 2008-08-14 22:49 artiste3 - titre3 (techno Remix).flv
-rw-r--r-- 1 aldian aldian     376 2008-08-16 23:27 ffmpeg_flv_to_mp3_ConversionScript.sh
-rw-r--r-- 1 aldian aldian    3872 2008-08-16 22:35 Massffmpeg.class
aldian@ubuntu:~/TEMP$ chmod +x ffmpeg_flv_to_mp3_ConversionScript.sh 
aldian@ubuntu:~/TEMP$ ll
total 20284
-rwxrwxrwx 1 aldian aldian 3544962 2008-08-14 20:21 artiste1 - titre1.flv
-rwxrwxrwx 1 aldian aldian 7865420 2008-08-14 19:30 artiste2 - titre2[HQ].flv
-rwxrwxrwx 1 aldian aldian 9305817 2008-08-14 22:49 artiste3 - titre3 (techno Remix).flv
-rwxr-xr-x 1 aldian aldian     376 2008-08-16 23:27 ffmpeg_flv_to_mp3_ConversionScript.sh
-rw-r--r-- 1 aldian aldian    3872 2008-08-16 22:35 Massffmpeg.class

exécution du script:

aldian@ubuntu:~/TEMP$ ./ffmpeg_flv_to_mp3_ConversionScript.sh 
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
  configuration: --enable-liba52 --disable-debug --enable-libfaad --enable-libfaac --enable-gpl --enable-x264 --enable-xvid --enable-pthreads --enable-libvorbis --enable-pp --enable-libtheora --enable-libogg --enable-libgsm --enable-swscaler --disable-debug --enable-shared --prefix=/usr
  libavutil version: 49.3.0
  libavcodec version: 51.38.0
  libavformat version: 51.10.0
  built on Aug 10 2008 11:48:19, gcc: 4.2.3 (Ubuntu 4.2.3-2ubuntu7)

Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 1.00 (1/1)
Input #0, flv, from 'artiste2 - titre2[HQ].flv':
  Duration: 00:03:07.0, start: 0.000000, bitrate: 224 kb/s
  Stream #0.0: Video: flv, yuv420p, 16x12,  1.00 fps(r)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 224 kb/s
Output #0, mp2, to 'artiste2 - titre2[HQ].mp3':
  Stream #0.0: Audio: mp2, 44100 Hz, stereo, 128 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
Press [q] to stop encoding
size=    2923kB time=187.1 bitrate= 128.0kbits/s    
video:0kB audio:2923kB global headers:0kB muxing overhead 0.000000%
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
  configuration: --enable-liba52 --disable-debug --enable-libfaad --enable-libfaac --enable-gpl --enable-x264 --enable-xvid --enable-pthreads --enable-libvorbis --enable-pp --enable-libtheora --enable-libogg --enable-libgsm --enable-swscaler --disable-debug --enable-shared --prefix=/usr
  libavutil version: 49.3.0
  libavcodec version: 51.38.0
  libavformat version: 51.10.0
  built on Aug 10 2008 11:48:19, gcc: 4.2.3 (Ubuntu 4.2.3-2ubuntu7)

Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 25.00 (25/1)
Input #0, flv, from 'artiste3 - titre3 (techno Remix).flv':
  Duration: 00:03:48.8, start: 0.000000, bitrate: 56 kb/s
  Stream #0.0: Video: flv, yuv420p, 320x384, 25.00 fps(r)
  Stream #0.1: Audio: mp3, 22050 Hz, mono, 56 kb/s
Output #0, mp2, to 'artiste3 - titre3 (techno Remix).mp3':
  Stream #0.0: Audio: mp2, 22050 Hz, mono, 128 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
Press [q] to stop encoding
size=    3567kB time=228.3 bitrate= 128.0kbits/s    
video:0kB audio:3567kB global headers:0kB muxing overhead 0.000000%
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
  configuration: --enable-liba52 --disable-debug --enable-libfaad --enable-libfaac --enable-gpl --enable-x264 --enable-xvid --enable-pthreads --enable-libvorbis --enable-pp --enable-libtheora --enable-libogg --enable-libgsm --enable-swscaler --disable-debug --enable-shared --prefix=/usr
  libavutil version: 49.3.0
  libavcodec version: 51.38.0
  libavformat version: 51.10.0
  built on Aug 10 2008 11:48:19, gcc: 4.2.3 (Ubuntu 4.2.3-2ubuntu7)

Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 29.97 (30000/1001)
Input #0, flv, from 'artiste1 - titre1.flv':
  Duration: 00:04:16.1, start: 0.000000, bitrate: 64 kb/s
  Stream #0.0: Video: flv, yuv420p, 320x240, 29.97 fps(r)
  Stream #0.1: Audio: mp3, 22050 Hz, mono, 64 kb/s
Output #0, mp2, to 'artiste1 - titre1.mp3':
  Stream #0.0: Audio: mp2, 22050 Hz, mono, 128 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
Press [q] to stop encoding
size=    4001kB time=256.1 bitrate= 128.0kbits/s    
video:0kB audio:4001kB global headers:0kB muxing overhead 0.000000%
finished

et pour conclure un petit aperçu du contenu du répertoire après éxécution du script et du contenu de celui-ci:

aldian@ubuntu:~/TEMP$ ll
total 30792
-rwxrwxrwx 1 aldian aldian 3544962 2008-08-14 20:21 artiste1 - titre1.flv
-rw-r--r-- 1 aldian aldian 4096836 2008-08-16 23:32 artiste1 - titre1.mp3
-rwxrwxrwx 1 aldian aldian 7865420 2008-08-14 19:30 artiste2 - titre2[HQ].flv
-rw-r--r-- 1 aldian aldian 2993005 2008-08-16 23:32 artiste2 - titre2[HQ].mp3
-rwxrwxrwx 1 aldian aldian 9305817 2008-08-14 22:49 artiste3 - titre3 (techno Remix).flv
-rw-r--r-- 1 aldian aldian 3652963 2008-08-16 23:32 artiste3 - titre3 (techno Remix).mp3
-rwxr-xr-x 1 aldian aldian     376 2008-08-16 23:27 ffmpeg_flv_to_mp3_ConversionScript.sh
-rw-r--r-- 1 aldian aldian    3872 2008-08-16 22:35 Massffmpeg.class
aldian@ubuntu:~/TEMP$ cat ffmpeg_flv_to_mp3_ConversionScript.sh 
#!/bin/bash
# 
# name: ffmpeg_flv_to_mp3_ConversionScript.sh
# input format: flv
# output format: mp3
# 
ffmpeg -ab 128k -i  artiste2\ -\ titre2[HQ].flv  artiste2\ -\ titre2[HQ].mp3 
ffmpeg -ab 128k -i  artiste3\ -\ titre3\ \(techno\ Remix\).flv  artiste3\ -\ titre3\ \(techno\ Remix\).mp3 
ffmpeg -ab 128k -i  artiste1\ -\ titre1.flv  artiste1\ -\ titre1.mp3 
echo "finished"

pour exécuter en un seul mot:

cd /usr/local/
sudo mkdir classes
sudo cp CHEMIN_VERS_VOTRE_REPERTOIRE_DE_TRAVAIL/Massffmpeg.class /usr/local/classes/
cd 
gedit .bashrc

et la pour poursuivre mon exemple de converion flv vers mp3, vous pouvez ajouter dans la section alias un alias du type suivant:

alias massfmp3='java -cp /usr/local/classes/ Massffmpeg -ab 128k -i typeSource flv typeDest mp3 && chmod +x ffmpeg_flv_to_mp3_ConversionScript.sh && ./ffmpeg_flv_to_mp3_ConversionScript.sh && rm ffmpeg_flv_to_mp3_ConversionScript.sh'

Désormais pour convertir les flv vers mp3 à un taux de 128kbits, il vous suffira de vous placer dans le dossier contenant les .flv et de taper massfmp3.

Dernière modification par Aldian (Le 19/08/2008, à 10:04)

Hors ligne

#2 Le 17/08/2008, à 13:24

AsTeR

Re : Programme pour faire de la conversion en masse avec ffmpeg.

Merci pour ce script qui peut être bien pratique !

Hors ligne

#3 Le 19/08/2008, à 09:49

Aldian

Re : Programme pour faire de la conversion en masse avec ffmpeg.

MAJ:

1) ajout du paragraphe: pour exécuter en un seul mot:
2) correction bug mineur: fichiers dont le nom contient une apostrophe

Dernière modification par Aldian (Le 19/08/2008, à 10:07)

Hors ligne

#4 Le 21/08/2008, à 20:23

r0

Re : Programme pour faire de la conversion en masse avec ffmpeg.

ce script a l'air bien pratique en effet.
il est codé en java, je connais pas trop, mais connaissant bien le C je peux dire que les idees sont bonnes.
beau boulot!

a quand le script shell? wink

Hors ligne

#5 Le 23/08/2008, à 17:50

Lapogne71

Re : Programme pour faire de la conversion en masse avec ffmpeg.

Salut,
je n'ai peut être pas compris, mais pourquoi ne pas utiliser (dans un script shell pur) une simple boucle "for" ?
Par exemple :

#!/bin/bash
for source_file in `ls *.flv` ; do
	name_file=`basename $source_file .flv`
	ffmpeg -i $source_file -ab 128k $name_file.mp3
done

Ensuite on peux optimiser le script en ajoutant les options de ffmpeg, par exemple :

#!/bin/bash

SOURCE_TYPE="flv"
DEST_TYPE="mp3"
FFMPEG_OPTIONS="-ab 128k"

for source_file in `ls *.$SOURCE_TYPE` ; do
	name_file=`basename $source_file .$SOURCE_TYPE`
	ffmpeg -i $source_file $FFMPEG_OPTIONS $name_file.$DEST_TYPE
done

Dernière modification par Lapogne71 (Le 23/08/2008, à 17:51)

Hors ligne

#6 Le 23/08/2008, à 20:42

Aldian

Re : Programme pour faire de la conversion en masse avec ffmpeg.

Parce que je suis nul en shell et absolument incapable de sortir comme ça ce type de script, même si je suis capable par extrapolation de comprendre le sens de ce que tu y fais. Sinon, effectivement ta solution est beaucoup plus simple, merci bcp smile

Hors ligne

#7 Le 23/08/2008, à 22:50

Lapogne71

Re : Programme pour faire de la conversion en masse avec ffmpeg.

Quand je vois ton programme en java, je me dit que le shell sera encore plus facile pour toi  ;-)

Hors ligne

#8 Le 18/09/2010, à 23:33

vandpatr

Re : Programme pour faire de la conversion en masse avec ffmpeg.

Bonsoir,
@Lapogne71
Un grand merci pour ton aide, j'étais nul de nul en shell!
J'ai légèrement modifier ton script :

#!/bin/bash

SOURCE_TYPE="flv"
DEST_TYPE="mp3"
FFMPEG_OPTIONS="-vn -ar 44100 -ac 2 -ab 192k -f mp3"

for source_file in `ls *.$SOURCE_TYPE` ; do
    name_file=`basename $source_file .$SOURCE_TYPE`
    ffmpeg -i $source_file $FFMPEG_OPTIONS $name_file.$DEST_TYPE
done

Une autre amélioration est de placer ce script dans le répertoire : /home/utilisateur/.gnome2/nautilus-scripts/
Ainsi en faisant un clique droit sur le ou les fichiers dans "Nautilus", le script est utilisé très facilement tout en étant  bien rangé.

capturelnn.png

J'espère avoir aidé!
@+

Dernière modification par vandpatr (Le 19/09/2010, à 01:30)

Hors ligne