Некоторые ogg-файлы не воспроизводятся в java (возможно, из-за размера?) - PullRequest
0 голосов
/ 19 октября 2018

У меня есть класс звука, который воспроизводит аудиофайлы.Однако некоторые ogg-файлы не работают при воспроизведении.Я не уверен, связано ли это с форматами файлов или размерами файлов.

Проблема, кажется, возникает с файлами небольшого размера, так как файлы, которые работают, имеют размер 6,7+ КБ или более, ите, которые не имеют 6 КБ или меньше.

Однако я попытался добавить сгенерированные тоны в конце одного из нефункциональных oggs с Audacity, увеличив файл до 7,5 КБ, но он все равно не работал.

Вот класс Sound, который я использовал для воспроизведения файлов:

<code>  import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
  import static javax.sound.sampled.AudioSystem.getAudioInputStream;

  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Arrays;

  import javax.sound.sampled.AudioFormat;
  import javax.sound.sampled.AudioInputStream;
  import javax.sound.sampled.AudioSystem;
  import javax.sound.sampled.DataLine.Info;
  import javax.sound.sampled.LineUnavailableException;
  import javax.sound.sampled.SourceDataLine;
  import javax.sound.sampled.UnsupportedAudioFileException;

  /**
   * The {@code Sound} class plays audio from a wav, ogg, or mp3 file
   * with wav working the best in a new thread
   * <p>
   * Here are some examples of how the {@code Sound} object can be initialized:
   * <blockquote><pre>
   *     Sound soundOne = new Sound("pathToFile/music.wav", true);
   *     Sound soundTwo = new Sound(new File("pathToFile/music.wav"), true);
   *     Sound soundThree = new Sound(ClassName.class.getResource(pathToFile/music.wav), true);
   * 
*

* Класс {@code Sound} включает методы для воспроизведения звука, остановки звука, изменения *громкость, получение продолжительности, если WAV, получить, остановлен ли звук, получить *, закончен ли звук, и изменить входной файл * * / public class Sound {/ ** * Должна ли музыка воспроизводиться вloop * / private boolean loopable;/ ** * Был ли указан URL * / private boolean isUrl;/ ** * String имя файла * / private String fileName;/ ** * URL-адрес файла * / частный URL-адрес fileUrl;/ ** * Громкость звука при * * / частная двойная громкость = 1,0;/ ** * Длительность аудиофайла в миллисекундах * / private double durationInMilliseconds;private ArrayList playingSounds = new ArrayList <> ();/ ** * Инициализирует вновь созданный объект {@code Sound} с именем файла String * @param fileName Путь к файлу, который будет воспроизводиться * @param loopable Независимо от того, должен ли звук воспроизводиться в цикле * @throws UnsupportedAudioFileException Брошенный, если файл являетсяне поддерживается * @throws IOException Брошенный, если есть проблема с данным файлом * / public Sound (String fileName, логический цикл) бросает UnsupportedAudioFileException, IOException {isUrl = false;this.fileName = fileName;this.loopable = loopable;if (fileName.endsWith (". wav")) {final File file = new File (fileName);AudioInputStream stream = AudioSystem.getAudioInputStream (file);AudioFormat format = stream.getFormat ();long frames = stream.getFrameLength ();durationInMilliseconds = 1000 * ((double) frames / format.getFrameRate ());}} / ** * Инициализирует вновь созданный объект {@code Sound} с использованием объекта File * @param inputFile Файл для воспроизведения * @param loopable Должен ли звук зацикливаться * @throws UnsupportedAudioFileException Брошенный, если файл не поддерживается* @throws IOException Брошенный, если есть проблема с данным файлом * / public Sound (Файл inputFile, логический цикл) бросает UnsupportedAudioFileException, IOException {isUrl = false;this.fileName = inputFile.toString ();this.loopable = loopable;if (fileName.endsWith (". wav")) {AudioInputStream stream = AudioSystem.getAudioInputStream (inputFile);AudioFormat format = stream.getFormat ();long frames = stream.getFrameLength ();durationInMilliseconds = 1000 * ((double) frames / format.getFrameRate ());}} / ** * Инициализирует вновь созданный объект {@code Sound} с помощью объекта URL * @param url URL-адрес аудиофайла * @param loopable Должен ли звук зацикливаться * @throws UnsupportedAudioFileException Брошенный, если файл не поддерживается* @throws IOException Брошенный, если есть проблема с данным файлом * / public Sound (URL-адрес, логический цикл) бросает UnsupportedAudioFileException, IOException {isUrl = true;fileUrl = url;String urlString = url.toString ();fileName = urlString.substring (Math.max (urlString.lastIndexOf ('\\'), urlString.lastIndexOf ('/')) + 1);this.loopable = loopable;if (fileUrl.getFile (). endWith (". wav")) {AudioInputStream stream = AudioSystem.getAudioInputStream (fileUrl);AudioFormat format = stream.getFormat ();long frames = stream.getFrameLength ();durationInMilliseconds = 1000 * ((double) frames / format.getFrameRate ());}} / ** * Воспроизведение аудио из указанного источника * / public final void play () {playingSounds.add (new PlayingSound ());} / ** * Останавливает воспроизведение звука * / public final void stop () {for (PlayingSound ps: playingSounds) ps.stop ();} / ** * Изменяет громкость звука * @param volume Volume для изменения на * / public final void changeVolume (double volume) {if (volume> 1 || volume <0) выдает новое IllegalArgumentException ("Ошибка: Volume mustбыть между 0 и 1 ");this.volume = объем;} / ** * AudioFormat для указания соглашения для представления данных * @param inFormat Формат аудиофайла * @return Необходимая информация о формате из inFormat * / private AudioFormat getOutFormat (AudioFormat inFormat) {final int ch = inFormat.getChannels ();конечная скорость с плавающей запятой = inFormat.getSampleRate ();вернуть новый AudioFormat (PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);} / ** * Дает длительность в миллисекундах, если файл .wav * @return Длительность в миллисекундах, если файл .wav * @throws Exception Выдается, если файл не является .wav * / public double getDuration () выдает исключение {if (! IsUrl && fileName.endsWith (". wav") || isUrl && fileUrl.getFile (). endWith (". wav")) return durationInMilliseconds;выбросить новое исключение («Ошибка: длина может быть определена только для файлов .wav»);} / ** * Возвращает, воспроизводится ли звук * @return Независимо от того, воспроизводится ли звук * / public public boolean isStopped () {for (PlayingSound ps: playingSounds) if (! Ps.isStopped ()) вернет false;вернуть истину;} / ** * Возвращает, закончил ли аудио воспроизведение (вышел из цикла) * @return Независимо от того, закончил ли аудио воспроизведение (вышел из цикла) * / public final boolean isFinished () {for (PlayingSound ps: playingSounds)) if (! ps.isFinished ()) return false;вернуть истину;} / ** * Изменяет место ввода для аудио * @param url URL для замены источника звука * @throws UnsupportedAudioFileException Брошенный, если файл не поддерживается * @throws IOException Брошенный, если есть проблема с данным файлом * /public final void changeInput (URL url) выбрасывает UnsupportedAudioFileException, IOException {isUrl = true;fileUrl = url;if (fileUrl.getFile (). endWith (". wav")) {AudioInputStream stream = AudioSystem.getAudioInputStream (fileUrl);AudioFormat format = stream.getFormat ();long frames = stream.getFrameLength ();durationInMilliseconds = 1000 * ((double) frames / format.getFrameRate ());}} private void removeInternalSound (PlayingSound ps) {playingSounds.remove (ps);} / ** * Возвращает громкость звука, установленную в данный момент на * @return Громкость звука * / public final double getVolume () {return volume;} @Overridepublic String toString () {return String.format ("String [имя:% s, loopable:% b]", fileName, loopable);} закрытый класс PlayingSound {приватный логический stop = false;приватный логический закончен = ложь;приватная тема playingSound;PlayingSound () {playingSound = new Thread (() -> {do {try {AudioInputStream in; if (! IsUrl) in = getAudioInputStream (new File (fileName)); еще в = getAudioInputStream (fileUrl); окончательный AudioFormat outFormat = getOutFormat(in.getFormat ()); окончательная информация Info = новая информация (SourceDataLine.class, outFormat); try (конечная строка SourceDataLine = (SourceDataLine) AudioSystem.getLine (info)) {if (line! = null) {line.open(outFormat); line.start (); AudioInputStream inputMystream = AudioSystem.getAudioInputStream (outFormat, in); поток (inputMystream, line); line.drain (); line.stop ();}}} catch (UnsupportedAudioFileException | LineUnavailableException |IOException e) {выбросить новое IllegalStateException (e);}} while (loopable &&! Stop); закончено = true; removeInternalSound (this);});playingSound.start ();} / ** * Потоковое аудио в микшер * @param в поле Входной поток в аудиофайл * @param line Где аудиоданные могут быть записаны в * @throws IOException Брошенный, если у данного файла есть какие-либо проблемы * / private void stream (AudioInputStreamв строке SourceDataLine) выдает IOException {byte [] buffer = new byte [4];for (int n = 0; n! = -1 &&! stop; n = in.read (buffer, 0, buffer.length)) {byte [] bufferTemp = новый байт [buffer.length];for (int i = 0; i > 8);} buffer = bufferTemp;line.write (буфер, 0, n);}} void stop () {stop = true;} boolean isStopped () {return stop;} boolean isFinished () {возврат завершен;}}}

Вот класс, который можно использовать для проверки вышеуказанного класса Sound, если вы замените pathToFile на путь к файлу:

import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.IOException;

public class Test {

    public static void main(String[] args) throws IOException, UnsupportedAudioFileException, InterruptedException {
        Sound test = new Sound("pathToFile", false);
        test.play();
        Thread.sleep(1000);
    }

}

Вот три рабочихogg файлы:

Файл a:

https://dl.dropboxusercontent.com/s/hwgor2xk0ief7ui/workingOne.ogg

Файл b:

https://dl.dropboxusercontent.com/s/4n14lxpvmw0ezpd/workingTwo.ogg

Файл c:

https://dl.dropboxusercontent.com/s/749zrcglz1jpfow/workingThree.ogg

Вот три сбойных файла ogg:

Файл d:

https://dl.dropboxusercontent.com/s/bwsu4ouwu06rfao/failedFile.ogg

Файл d плюс дополнительные сгенерированные тоныувеличить размер, превышающий размер рабочего файла a выше:

https://dl.dropboxusercontent.com/s/t7q4wmh4ljqvz3a/failedFile2.ogg

Файл e:

https://dl.dropboxusercontent.com/s/tddn22crdkvwawl/click.ogg

Может бытьнесколько библиотек, необходимых для работы с файлами ogg, работающими с данным классом.Если никакие файлы не работают, скомпилируйте библиотеки в указанном zip с помощью указанных программ (возможно, используя IDE):

Включены библиотеки (java jar): JLayer 1.0.1, Jogg 0.0.7, JOrbis 0.0.17-1, MP3 SPI 1.9.5, Tritonus-share 0.3.7.4 и Ogg Vorbis SPI 1.0.3.

https://dl.dropboxusercontent.com/s/tqrj5w4vs32a3h8/lib.zip

ОБНОВЛЕНИЕ:

Я добавил много тембра, добавленного ранее в файл d (стоимостью 30 секунд), в файл d дляпосмотрим, изменит ли это что-нибудь, и это сработало.

Итак, я решил начать обрезку звука до точки, когда звук не воспроизводился.

Как ни странно, я обрезал короче, чем файл dдлина, и это работало, пока я не сократил до определенной точки.

Давайте назовем более короткую версию файла d, которая работает файл f, и ту, которая короче этого и не работает файл g.

Кроме того, если я изменю настройку качества экспорта с 10/10 на 5/10 в Audacity, программное обеспечение, в котором я это сделал, воспроизведение не будет работать.Давайте назовем этот файл h.

Вот каждый из вышеупомянутых файлов:

Файл f:

https://dl.dropboxusercontent.com/s/ore4bfgb0va2gw7/fileF.ogg

Файл g:

https://dl.dropboxusercontent.com/s/zq000zhlup9hiu1/fileG.ogg

Файл h:

https://dl.dropboxusercontent.com/s/4ojj7gv9x92z9mi/fileH.ogg

...