Java - AAC MP4 - Как получить длину носителя?

Кто-нибудь знает, как получить длину носителя аудио в формате aac (аудиоформат) mp4 (формат файла) в Java?

Любая помощь будет высоко оценен.


person user3489820    schedule 02.09.2014    source источник


Ответы (4)


Вот решение, которое я нашел (используя mp4parser на github):

public static long getAudioLength(byte[] content) throws Exception {
    IsoFile isoFile = new IsoFile(new MemoryDataSourceImpl(content));
    double lengthInSeconds = (double)isoFile.getMovieBox().getMovieHeaderBox().getDuration() / isoFile.getMovieBox().getMovieHeaderBox().getTimescale();
    return (long)lengthInSeconds;
}
person user3489820    schedule 02.09.2014

muxer (упомянутый @user3489820) был создан из mp4parser и теперь живет отдельно по адресу: org.mp4parser/muxer . Пакет Maven был изменен на org.mp4parser/mp4parser. Для получения дополнительной информации см. https://mvnrepository.com/artifact/org.mp4parser/isoparser и просмотрите IsoParser, мультиплексор и потоковая передача JavaDoc.

Я обновил пример кода @user3489820, добавил импорт, убрал избыточный код и устранил ненужные приведения типов. Я также удалил вызов MemoryDataSourceImpl, потому что моему проекту нужно было определить длину файла MP4 на диске, а этот класс был не нужен:

import java.io.File;
import org.mp4parser.IsoFile;
import org.mp4parser.boxes.iso14496.part12.MovieHeaderBox;

public class Blah {
    public static long getAudioLength(File file) throws Exception {
        IsoFile isoFile = new IsoFile(file);
        MovieHeaderBox mhb = isoFile.getMovieBox().getMovieHeaderBox();
        return mhb.getDuration() / mhb.getTimescale();
    }
}
person Mike Slinn    schedule 06.06.2019

Вы можете попробовать этот код...

Файл файл = новый файл («имя файла.mp3»); AudioFileFormat baseFileFormat = новый MpegAudioFileReader().getAudioFileFormat(файл); Свойства карты = baseFileFormat.properties(); Длительная продолжительность = (Длительная) properties.get("duration");

person Aditya    schedule 02.09.2014
comment
Это MP3, а не AAC. MpegAudioFileReader предназначен для MP3 - person user3489820; 02.09.2014
comment
На данный момент я застрял в JAAD. Проблема в том, что файл mp4, который я пытаюсь разобрать, в конце содержит образцы таблиц. Это означает, что мне нужен RandomAccessFile для его разбора, но у меня есть только ByteArrayInputStream. Итак... Одним из решений является воссоздание файла в файловой системе (и это плохо для сервера)... хотя мне это решение не нравится - person user3489820; 02.09.2014
comment
Пробовал, не нашел как работать с in-memory aac файлами (т.е. из ByteArrayInputStream или просто byte[] ) - person user3489820; 02.09.2014
comment
Наконец, нашел решение с парсером mp4 (это не от Google, это просто код Google). - person user3489820; 02.09.2014
comment
Хорошо, нашел. Надо было уделить больше времени, чтобы попробовать с парсером mp4 - person user3489820; 02.09.2014

Вы можете использовать ffmpeg для получения продолжительности любого носителя:

Сначала получите вывод команды из среды выполнения:

  public String execute(String cmd) {
    String output=null;
      try {
        Runtime rt = Runtime.getRuntime();
        Process pr=rt.exec(cmd);
        final InputStream es=pr.getErrorStream();
        class C extends Thread {
          String type, output="";
          InputStream is;
          public C(InputStream is, String type) { this.is=is; this.type=type; }
          public void run() {
            try {
              InputStreamReader isr = new InputStreamReader(is);
              BufferedReader br = new BufferedReader(isr);
              String line=null;
              while((line=br.readLine())!=null)
                output+=line+" ";
            }
            catch (IOException ioe) { ioe.printStackTrace(); }
          }
        };
        C t=new C(es);
        t.start();
        int exitVal=pr.waitFor();
        System.out.println("ExitValue: " + exitVal);
        output=""+t.output;
      }
      catch(Throwable t) { t.printStackTrace(); }
      return output;
  }

Затем проанализируйте вывод для «Длительности»:

  public int getTime(String out) {
    int i=0, j=0, k, l, x=0, y=0, ind=0;
    String d="", frs="";
    BufferedReader dis=null;
    String nextline=out;
    ind=0;
    if((ind=nextline.indexOf("Duration:"))>-1)
      d=nextline.substring(ind+9, nextline.indexOf(',', ind+1)).trim();
      int ind2=0;
      int h=0, m=0, s=0, xxx=0;
      if((ind=d.indexOf(":"))>-1) {
        h=Integer.parseInt(d.substring(ind2, ind));
        ind2=ind+1;
      }
      if((ind=d.indexOf(":", ind+1))>-1) {
        m=Integer.parseInt(d.substring(ind2, ind));
        ind2=ind+1;
      }
      if((ind=d.indexOf(".", ind+1))>-1) {
        s=Integer.parseInt(d.substring(ind2, ind));
      }
      if(ind<d.length()) {
        ind2=ind+1;
        if((ind=d.indexOf(".", ind+1))>-1) {
          xxx=Integer.parseInt(d.substring(ind2, d.length()));
        }
      }
      try {
        dis.close();
      }
      catch (Exception ex) { }
    return h*3600+m*60+s;
  }

В целом:

  String out=execute("ffmpeg -i myfile.mp4");
  int time=getTime(out);
person gpasch    schedule 29.07.2019