IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Boucle avec une commande ffmpeg


Sujet :

Langage Java

  1. #1
    Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2012
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2012
    Messages : 109
    Points : 47
    Points
    47
    Par défaut Boucle avec une commande ffmpeg
    bonjour

    quand je fait une commande msdos dans le terminal tous marche tres bien

    mes si je mes dans une boucle java une commande msdos avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
             Runtime rt = Runtime.getRuntime(); 
     
    Process p = rt.exec(Dapp+" -i  "+FichierAconvertire+" "+ FichierResultat );
    ca ne marche pas l’interface fait avec javafx bug est ce bloque.

    bizarrement si je fait convertir plusieurs fichiers audio comment mp3

    et que par la suite je quitte l'application alors la convertirons ce fait au bou de 1 minutes.

    c'est une commande dos pour l'application ffmpeg

    pouvez vous m'aider

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    C'est probablement parce que tu ne consommes pas le flux de sortie, ou peut-être que quelque chose doit être passé dans le flux d'entrée, et, quand tu fermes l'application, ça doit fermer les flux et libérer quelque chose qui fait que ffmpeg se termine.

    Au lieu d'utiliser Runtime.exec qui date et est particulièrement compliqué à utiliser, utilise plutôt ProcessBuilder et gère correctement les flux. Voir toutes les explications ici.

  3. #3
    Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2012
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2012
    Messages : 109
    Points : 47
    Points
    47
    Par défaut
    Salut,

    Peux-tu me donner un exemple de code ?

    En faisant des recherches sur le net, j'ai trouvé des codes où le ProcessBuilder marche avec Runtime.getRuntime();

    Les 2 sont liés ?

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kalare Voir le message
    En faisant des recherches sur le net, j'ai trouvé des codes où le ProcessBuilder marche avec Runtime.getRuntime();

    Les 2 sont liés ?
    Tu confonds peut-être ProcessBuilder et Process. ProcessBuilder est lié quelque part à la méthode exec() de Runtime dans la mesure où ProcessBuilder permet de faire plus simplement ce qu'on fait avec Runtime.getRuntime().exec( ... ). Les deux créent au final un Process. Mais normalement, si on utilise ProcessBuilder, il n'y aucune raison d'utilsier Runtime.getRuntime().exec en même temps, ça ne sert à rien de continuer d'utiliser ce dernier.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    File workdir = new File( ... ); // le dossier de travail pour lancer la commande 
    String[] command = {"ffmpeg.exe", /* les paramètres * /}; 
    ProcessBuilder processBuilder = new ProcessBuilder(command).directory( workdir ); 
     
    		try {
    			processBuilder.inheritIO(); // ici on lit le process avec les entrées/sorties de Java (donc System.in, System.out, et System.err)
    			Process process = processBuilder.start(); // on démarre le process
    			process.waitFor(); // on attend qu'il se termine
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (InterruptedException e) {
    		}
    Il faudra peut-être que tu adaptes : pour les sorties, au pire ça ira dans la console, pour les entrées, s'il y en a, si tu veux ne pas avoir à interagir au clavier pendant l'exécution de ton programme, il faudra le simuler en envoyant du texte correspondant à ce que tu taperais en console pour répondre aux questions que te poserais le programme si tu le lançais en consoel, ce qui va se faire avec les méthode redirect de ProcessBuilder.
    Exemple de principe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    		ProcessBuilder processBuilder = new ProcessBuilder( command ).directory(directory);
    		processBuilder.redirectInput(Redirect.PIPE); // pour pouvoir écrire dans lans l'entrée standard du process
    		processBuilder.redirectOutput();// balance la sortie standard du process dans System.out du programme Java
    		processBuilder.redirectError();// balance la sortie standard d'erreur du process dans System.err du  Java
    		Process process = processBuilder.start(); // lancementdu process
     
            try(PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(process.getOutputStream())))) {
            	writer.println("blahblah"); // ici c'est comme si tu entrais quelque chose au clavier lorsque tu exécutes en console (si le programme te pose une question)
            }
    Tu as tout le détail dans le lien que je t'ai donné, et il y a la JavaDoc aussi. Il y a un exemple de principe (l'exe c'est un java avec un programme en Java) ici.

    A noter que pour le tableau command (dans l'exemple ci-dessus), chaque partie de la commande (séparées par des espaces quand tu la tapes en console) est dans une cellule différente, contrairement à ce que tu fais dans ton exemple avec Runtime.exec() où tu passes la commande sous forme d'une String unique, ce qui poser différents soucis en fonction de l'os, des caractères de séparation, etc. Parce qu'il y a une différence importante entre taper une commande dans une console (y compris de lancement d'un exe) et l'usage de Runtime.exec() et ProcessBuilder : dans le second cas, on exécute toujours un exe, il n'y a pas de shell qui pourrait simplifier la syntaxe (au mieux tu peux configurer l'environnement (les variables systèmes), et le dossier de travail (là où va s'exécuter la commande, ce qui correspond plus ou moins à l'endroit où tu vas quand tu fais "cd" en console avant de lancer la commande en console).

  5. #5
    Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2012
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2012
    Messages : 109
    Points : 47
    Points
    47
    Par défaut
    merci

    merci ça marche mes ma fenêtre de l'application ce bloque .
    je crois qu'il faut un thread ?

    mes comment mettre un thread dans une méthode ?

    merci

  6. #6
    Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2012
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2012
    Messages : 109
    Points : 47
    Points
    47
    Par défaut MERCI
    merci

    j'ai mis un thread sur la méthode est il n'y a plus de blocage.

    merci merci.

    sinon tu peu m'expliquer ce code : >>> processBuilder.inheritIO();

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Juin 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Juin 2017
    Messages : 3
    Points : 6
    Points
    6
    Par défaut
    Lorsque tu met un EventListener à une fenêtre, et qu'un evenement a lieu, le Thread qui s'occupe de la gestion d'evenement appelle la méthode que tu as definis dans le EventListener, donc tant qu'elle est pas terminée, on ne peut pas s'occuper d'autre évenements. Donc dans la méthode de L'EventListener il faut que tu crées et lances un nouveau Thread: https://alwin.developpez.com/tutorial/JavaThread/

  8. #8
    Membre du Club
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2012
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2012
    Messages : 109
    Points : 47
    Points
    47
    Par défaut
    j'ai mis un thread

    et le probleme est résolut mes j'ai un autre probleme.

    le probleme est que j'eesaye d'avoir un decompte dans un label des fichiers a convertire

    mes au lieu de faire uun decompte genre 5-4-3-2-1-0 il m'affiche directement le nombre de fichier a convertire donc il affiche 5

    comment faire pour avoir un decompte est non le total des fichiers a convertire

    voila le petit code que j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      IdCompte.setText("..."+a);

  9. #9
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kalare Voir le message
    j'ai mis un thread sur la méthode est il n'y a plus de blocage.
    C'est-à-dire ?

    Citation Envoyé par kalare Voir le message
    sinon tu peu m'expliquer ce code : >>> processBuilder.inheritIO();
    Un programme a potentiellement des entrées et des sorties, sous forme de flux qu'il faut consommer. Ces entrées et sorties se concrétisent respectivement par des saisies (clavier la plupart du temps) et affichage en console. Lorsqu'on exécute un programme externe, s'il a des entrées et/ou des sorties, il faut les consommer. Par exemple, si le programme a des entrées au clavier, il attendra tant qu'on a pas saisi quelque chose. Il est nécessaire de consommer les flux et d'entrée et sortie dans des processus séparés sinon il y a blocage. La méthode inheritIO câble automatiquement les entrées et sorties du programme externe sur celles de Java en s'occupant des les paralléliser dans des threads.

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kalare Voir le message
    j'ai mis un thread

    [...]
    voila le petit code que j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      IdCompte.setText("..."+a);
    Attention avec les threads dans des actions d'UI : Swing dispose de son propre thread (L'Event Dispatch Thread) et il est indispensable que les ordres Swing soient effectués dans ce thread (comme par exemple un setText() sur un JLabel).


    Citation Envoyé par kalare Voir le message
    j'ai mis un thread

    le probleme est que j'eesaye d'avoir un decompte dans un label des fichiers a convertire

    mes au lieu de faire uun decompte genre 5-4-3-2-1-0 il m'affiche directement le nombre de fichier a convertire donc il affiche 5
    comment faire pour avoir un decompte est non le total des fichiers a convertire
    C'est probablement que le décompte est fait dans l'Event Dispatch Thread. Le problème est qu'un thread effectue qu'une seule instruction à la fois. Il est donc impossible de voir les résultats d'étapes intermédiaires d'une boucle par exemple.

    Ce serait quand même plus qu'utile voire indispensable de voir ton code pour pouvoir te répondre précisément et en pas avoir à faire des suppositions. En plus tu parles d'avoir mis un thread quelque part : je me demande bien où...

    Maintenant, pour la théorie, lorsqu'on lance une opération dans une action d'UI (par exemple sur un clic de bouton) susceptible d'être longue, ou bloquante, ou pouvant avoir besoin de mettre à jour l'UI dans des étapes intermédiaires (comme une barre de progression ou l'affichage d'un décompte), on utilise un thread qui lance les traitement Swing dans l'Event Dispatch Thread par SwingUtilties.invokeLater(). Ou, mieux et plus simple, on utilise un SwingWorker qui va simplifier cette implémentation.

    Un exemple de principe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.util.List;
    import java.util.stream.Stream;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingWorker;
     
    public class ExempleSwingWorker {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Exemple");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		String[] files = Stream.iterate(1, i->i+1).limit(10).map(i->"Fichier "+i).toArray(String[]::new);
     
    		JPanel panel = new JPanel(new GridBagLayout());
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.gridx=0;
    		gbc.gridy=GridBagConstraints.RELATIVE;
     
    		JLabel label = new JLabel("");
    		panel.add(label, gbc);
    		JButton button = new JButton("Lancer");
    		panel.add(button, gbc);
     
    		frame.add(panel);
     
    		button.addActionListener(e-> lancerAction(files, label, button));
     
    		frame.setSize(300, 300);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    		System.out.println("pour");
     
    	}
     
    	private static void lancerAction(String[] files, JLabel label, JButton button) {
    		button.setEnabled(false);
    		SwingWorker<Object,String> swingworker = new SwingWorker<Object, String>() {
     
    			@Override
    			protected Object doInBackground() throws Exception {
    				for(int i=0; i<files.length; i++) {
    					publish("Traitement "+ (i+1)+"/"+files.length + " : " + files[i]); // on produit une donnée pour mettre à jour l'affichage
    					Thread.sleep(1000); // ici je simule un traitement qui prend du temps (1 seconde), ce qui pourrait être le lancement de ta commande externe
    				}
    				return null;
    			}
     
    			/**
                             * Dans cette méthode on modifie l'affichage ou tout ce qui concerne l'UI
                             * @param chunks
                             */
    			@Override
    			protected void process(List<String> chunks) {
    				// il n'y a besoin que d'afficher le dernier
    				label.setText(chunks.get(chunks.size()-1));
    			}
     
    			/**
                             * Cette méthode est exécuté à la fin
                             * @param chunks
                             */
    			@Override
    			protected void done() {
    				label.setText("fini");
    				button.setEnabled(true);
    			}
     
    		};
    		swingworker.execute();
    	}
     
     
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Une boucle avec la command PING
    Par alid0381 dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 08/06/2012, 10h40
  2. [Batch] Une boucle avec la command PING
    Par alid0381 dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 06/06/2012, 12h33
  3. Une boucle avec la command PING
    Par alid0381 dans le forum Windows
    Réponses: 0
    Dernier message: 30/05/2012, 20h38
  4. [System][EXEC] Probleme d'execution avec une commande parametrée.
    Par chicorico dans le forum Général Java
    Réponses: 15
    Dernier message: 20/05/2005, 15h07
  5. [Runtime]exec() avec une commande paramétrée
    Par nice dans le forum Général Java
    Réponses: 9
    Dernier message: 12/05/2005, 13h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo