2015-05-18 2 views
0

Мой сценарий генерирует видео из некоторых изображений .jpg, которые отлично работают. Кроме того, он добавляет аудиопоток из уже существующего файла .flac. Код работает довольно хорошо с небольшими аудиофайлами. Но, используя мой фактический файл, который находится вокруг 1GB я получаю следующее предупреждение/исключение:Декодирование большого аудиофайла usind Xuggler

22:00:03.366 [main] WARN com.xuggle.xuggler - error: not enough memory in internal frame buffer (../../../../../../../csrc/com/xuggle/xuggler/StreamCoder.cpp:1768) 
Exception in thread "main" java.lang.RuntimeException: failed to encode audio 
    at com.xuggle.mediatool.MediaWriter.encodeAudio(MediaWriter.java:855) 
    at diaporama.Renderer.renderVideo(Renderer.java:129) 
    at diaporama.Renderer.<init>(Renderer.java:32) 
    at Run.main(Run.java:24) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

Я предполагаю, что не хватает памяти для буферизации большого аудиофайла. Но я пытаюсь найти решение для этого. Есть ли у кого-нибудь какие-либо предложения о том, как надежно работать с большими аудиофайлами в этом отношении?

Это мой код:

private void renderVideo() { 
    final IMediaWriter writer = ToolFactory.makeWriter(this.outputFileName); 

    // video stream 
    writer.addVideoStream(0, 0, this.videoCodec, this.width, this.height); 

    // audio stream 
    IContainer containerAudio = IContainer.make(); 
    containerAudio.open(this.audioFile.getPath(), IContainer.Type.READ, null); 
    IStreamCoder coderAudio = containerAudio.getStream(0).getStreamCoder(); 
    if (coderAudio.open(null, null) < 0) 
     throw new RuntimeException("Cannot open audio coder"); 
    writer.addAudioStream(1, 0, this.audioCodec, coderAudio.getChannels(), coderAudio.getSampleRate()); 

    // video rendering 
    // ... video rendering takes place here ... 

    // audio rendering 
    System.out.println("Adding audio file: " + this.audioFile.getPath() + " to stream"); 

    // read audio file and create stream 
    IPacket packetaudio = IPacket.make(); 
    IAudioSamples samples; 

    while (containerAudio.readNextPacket(packetaudio) >= 0) { 
      /* 
      * We allocate a set of samples with the same number of channels as the 
      * coder tells us is in this buffer. 
      * 
      * We also pass in a buffer size (1024 in our example), although Xuggler 
      * will probably allocate more space than just the 1024 (it's not important why). 
      */ 
     samples = IAudioSamples.make(1024, coderAudio.getChannels()); 

      /* 
      * A packet can actually contain multiple sets of samples (or frames of samples 
      * in audio-decoding speak). So, we may need to call decode audio multiple 
      * times at different offsets in the packet's data. We capture that here. 
      */ 
     int offset = 0; 

      /* 
      * Keep going until we've processed all data 
      */ 
     while (offset < packetaudio.getSize()) { 
      int bytesDecoded = coderAudio.decodeAudio(samples, packetaudio, offset); 
      if (bytesDecoded < 0) 
       throw new RuntimeException("got error decoding audio in: " + this.audioFile); 
      offset += bytesDecoded; 
       /* 
       * Some decoder will consume data in a packet, but will not be able to construct 
       * a full set of samples yet. Therefore you should always check if you 
       * got a complete set of samples from the decoder 
       */ 
      if (samples.isComplete()) { 
       writer.encodeAudio(1, samples); 
      } 
     } 

    } 

    coderAudio.close(); 
    containerAudio.close(); 

    writer.close(); 
} 

ответ

0

Сколько памяти вы даете JVM? Вероятно, вы должны увеличить максимально допустимый размер кучи, с -Xmx4g (для кучи 4Gb) или что-то в этом роде. Здесь много вариантов.

Поскольку Xuggle, похоже, является родной библиотекой, размер кучи нативной также может быть небольшим. Это сложнее вылечить, но вы можете хотя бы убедиться, что вы используете 64-битную версию JVM.

Если вы используете некоторую среду IDE, эти параметры можно установить как run-configuration.