Durata di un file video in JAVA

di il
8 risposte

Durata di un file video in JAVA

Buongiorno a tutti.

Cerco una libreria per calcolare la durata di file video (per TUTTI I FORMATI video: flv, mpeg, avi, mp4) con Java.

Ho provato con la "getDuration()" della classe "player" del package javax.media, funziona per certi formati ma non per altri, quindi l'ho scartata.

Ho provato con jffmpeg (net.sourceforge.jffmpeg.VideoDecoder), ecco il codice:
-------------------------
String JFFMPEG_VIDEO = "net.sourceforge.jffmpeg.VideoDecoder";
Codec video = (Codec) Class.forName(JFFMPEG_VIDEO).newInstance();
PlugInManager.addPlugIn(JFFMPEG_VIDEO,
video.getSupportedInputFormats(),
video.getSupportedOutputFormats(null),
PlugInManager.CODEC);
-------------------------

ma non capisco in che attributo della classe video è contenuta la durata del file, per la verità non so neanche come passare alla classe video il percorso fisico del file video...

Qualcuno sa lenire la mia profonda frustrazione?
Grazie

Andrea

8 Risposte

  • Re: Durata di un file video in JAVA

    Scusa ma quali formati non ti riconosce la "prima" libreria? ti dà un qualche errore?
  • Re: Durata di un file video in JAVA

    Ciao,
    A me funziona solo con i file .mpeg.

    Il codice è il seguente:

    File f = new File(localFileName);
    int size = (int) f.length();

    URL a = f.toURL();
    Player player = Manager.createRealizedPlayer(new MediaLocator(a));
    (o alternativamente Player player = Manager.createRealizedPlayer(a);)
    Time t = player.getDuration();
    totSeconds = (int) t.getSeconds();

    Nb: Ovviamente le classi Manager e Player appartengono al package javax.media;

    L'errore che mi ritorna (nel caso ad esempio di un file avi ma è vero anche per tutti gli altri escluso come detto l'mpeg) è CannotRealizeException.

    grazie
  • Re: Durata di un file video in JAVA

    Sinceramente non conosco nessuna libreria che faccia quello che tu chiedi...ma facendo una breve ricerca credo che questo possa fare al caso tuo
    http://fobs.sourceforge.net
  • Re: Durata di un file video in JAVA

    Grazie mille, la libreria riesce a calcolare la durata di video per ogni formato.

    Il problema adesso (che non avevo specificato nel post iniziale) è che ho bisogno di farla girare anche sul Mac (oltre che su windows). Ora come ora riesco a farla funzionare solo su windows (mettendo la dll sotto system32)...
  • Re: Durata di un file video in JAVA

    Quello che non capisco è: se mi interessa calcolare la durata in un'applicazione java, è perchè voglio che il mio .jar sia multipiattaforma. Allora perchè devo copiare a mano una dll nella cartella system32 (nel caso di Windows)? Non basta la java virtual machine?

    grazie
  • Re: Durata di un file video in JAVA

    Ma infatti non devi copiare la libreria...almeno credo.

    puoi semplicemente caricarla tramite un system.loadlibrary();

    cerca maggiori dettagli al riguardo però;)
  • Re: Durata di un file video in JAVA

    Ciao barnabo, io sto cercando di fare più o meno la stessa cosa che stai facendo tu, ma utilizzando l'eseguibile ffmpeg.
    Premetto subito (come presentazione) che non sono un abile sviluppatore Java in quanto mi occupo di altro, ma pensavo fosse una cosa abbastanza semplice da fare.

    Ho creato un programmino, distribuito in un JAR. All'interno del Jar ho copiato due versioni, una per Windows e l'altra per Mac, dell'eseguibile ffmpeg.

    Ora, quando eseguo il Jar, questo estrae in una directory temporanea l'eseguibile corretto (se mi trovo su Windows: ffmpeg.exe, se mi trovo si Mac: ffmpeg) e poi prova ad eseguire il processo.

    Per facilità, quando estraggo l'eseguibile, mi faccio stampare a video il path dello stesso.
    Il problema è semplice: se eseguo sotto Windows riesco ad eseguire correttamente l'eseguibile, se provo da Mac non ricevo nessuna risposta (ma neanche nessuna eccezione) da ffmpeg. Ma la cosa più strana è che se tramite altra finestra terminale provo ad eseguire ffmpeg dalla directory temporanea, tutto funziona correttamente.

    Posto un pò di codice:

    Questo è il main
    
        public static void main(final String[] args) 
            throws URISyntaxException, 
            ZipException, 
            IOException 
        { 
            final URI uri; 
            final URI exe; 
            String asstio = "";
            String osType = "";
            
            try
            {
                uri = getJarURI(); 
    
                osType= System.getProperty("os.name");
    
                if(osType.substring(0, 3).equalsIgnoreCase("win"))
                {
                    //if win
                    exe = getFile(uri, "ffmpeg.exe"); 
                    asstio = exe.toString().replaceFirst("file:/C:", "C:");        
                }
                else
                {
                    //if mac
                    exe = getFile(uri, "ffmpeg"); 
                    asstio = exe.toString().replaceFirst("file:", "");
                }
    
                System.out.println("");
                System.out.println(asstio); 
                System.out.println("");
            }
            catch(Exception eex)
            {
                System.out.print(eex.getMessage());
            }
            
            System.out.println("Inserisci nome file video (completo di percorso (INVIO PER FINIRE)"); 
            BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
            String s;
            while ((s = sin.readLine()) != null && s.length() != 0)
            {
                break;
            }
    
            System.out.println("");
    
            try
            {
                Process child = null;
                if(osType.substring(0, 3).equalsIgnoreCase("win"))
                {
                    System.out.println(asstio + " -i \"" + s + "\"");
                    child = Runtime.getRuntime().exec(asstio + " -i \"" + s + "\"");
                }
                else
                {
                    System.out.println(asstio + " -i \"" + s + "\"");
                    child = Runtime.getRuntime().exec(asstio + " -i \"" + s + "\"");
                }
    
                System.out.println("");
    
                InputStream lsOut = lsOut = child.getErrorStream();
                InputStreamReader r = new InputStreamReader(lsOut);
                BufferedReader in = new BufferedReader(r);
    
                String line;
                while ((line = in.readLine()) != null)
                {
                    if(line.contains("Duration:"))
                    {
                        line = line.replaceFirst("Duration: ", ""); 
                        line = line.trim();
                        
                        System.out.println("DURATA: " + line.substring(0, 11));
                        break;
                    }
                            
                }
            } 
            catch (Exception e) 
            { 
                System.out.println("Command failed! " + e.getMessage());
            }
    
        } 
    Il metodo che estrae l'eseguibile nella directory temporanea:
    
        private static URI extract(final ZipFile zipFile, 
        final String fileName) 
        throws IOException 
        { 
            final File tempFile; 
            final ZipEntry entry; 
            final InputStream zipStream; 
            OutputStream fileStream; 
    
            tempFile = File.createTempFile(fileName, ""); 
            tempFile.deleteOnExit(); 
            
            entry = zipFile.getEntry(fileName); 
            
    
            if(entry == null) 
            { 
                throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName()); 
            } 
    
            zipStream = zipFile.getInputStream(entry); 
            fileStream = null; 
    
            try 
            { 
                final byte[] buf; 
                int i; 
    
                fileStream = new FileOutputStream(tempFile); 
                buf = new byte[1024]; 
                i = 0; 
    
                while((i = zipStream.read(buf)) != -1) 
                { 
                    fileStream.write(buf, 0, i); 
                } 
            } 
            finally 
            { 
                close(zipStream); 
                close(fileStream);
                
                tempFile.setExecutable(true, true);
                tempFile.canExecute();
            } 
    
            return (tempFile.toURI()); 
        } 
    
    Pensavo che fosse una questione di permessi, così ho fatto vari tentativi ad esempio dando 777 al file temporaneo ma il non riesco ancora a farlo funzionare correttamente.

    Spero di avere qualche dritta e che ti possa essere utile il codice (mancano alcuni metodi ovviamente, in caso funzionasse ti passo il tutto)
    tozoo
  • Re: Durata di un file video in JAVA

    Giusto per completezza, ho risolto il problema ed ora riesco ad invocare la getDuration tramite eseguibile ffmpeg inserito nel Jar da codice (a differenza delle classi della libreria mediaplayer funziona con avi, flv, mpeg, mp4, wmv... non ho testato su altri formati).

    Il problema dell'invocazione della linea di comando per ffmpeg su Mac (e credo sia risolutiva anche per Unix/Linux ma non ho provato) è stata inserire la linea di comando all'interno di uno script sh (con deleteonexit in modo da non lasciare file su disco al termine) e poi eseguire il processo:

    /bin/sh cmd.sh

    Nel file cmd.sh ci sarà il comando:

    ffmpeg -i nomevideo

    Ovviamente ho omesso tutti i path assoluti delle cartelle temporanee.

    Se qualcuno ha bisogno posso postare codice completo!


    Tozoo
Devi accedere o registrarti per scrivere nel forum
8 risposte