Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Fix: Windows URL Decoding #24

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

Supernova1114
Copy link

Test Environment: Windows 10, Java JDK 23

ffsampledsp throws a FileNotFoundError when a path to an audio file contains a space character.

String workingURL = "C:\\Users\\Super\\Downloads\\temp\\audio.ogg"; // Does not contain space
String nonWorkingURL = "C:\\Users\\Super\\Downloads\\temp\\temp Again\\audio.ogg"; // Contains space

FFAudioFileReader reader = new FFAudioFileReader();

try {
    System.out.println("Testing Working URL");
    reader.getAudioFileFormat(Paths.get(workingURL).toUri().toURL()); // Success
    System.out.println("Testing Non-Working URL");
    reader.getAudioFileFormat(Paths.get(nonWorkingURL).toUri().toURL()); // throws FileNotFoundError
} catch (UnsupportedAudioFileException | IOException e) {
    e.printStackTrace();
}

Output:

Testing Working URL
urlToString() input: file:/C:/Users/Super/Downloads/temp/audio.ogg
Testing Non-Working URL
urlToString() input: file:/C:/Users/Super/Downloads/temp/temp%20Again/audio.ogg
java.io.FileNotFoundException: file:C:/Users/Super/Downloads/temp/temp%20Again/audio.ogg
	at com.tagtraum.ffsampledsp.FFAudioFileReader.getAudioFileFormatsFromURL(Native Method)
	at com.tagtraum.ffsampledsp.FFAudioFileReader.lockedGetAudioFileFormatsFromURL(FFAudioFileReader.java:285)
	at com.tagtraum.ffsampledsp.FFAudioFileReader.getAudioFileFormats(FFAudioFileReader.java:177)
	at com.tagtraum.ffsampledsp.FFAudioFileReader.getAudioFileFormat(FFAudioFileReader.java:198)
	at test_stuffs.Main.main(Main.java:24)

FFAudioFileReader -> urlToString(final URL url) is called to convert the URL to a valid string input for FFmpeg:
Working input url: file:/C:/Users/Super/Downloads/temp/audio.ogg
Non-Working input: file:/C:/Users/Super/Downloads/temp/temp%20Again/audio.ogg

The native ff_open_format_context() function within FFUtils.c throws the FileNotFoundError in question.
It seems that although file:/C:/Users/Super/Downloads/temp/temp%20Again/audio.ogg the %20 encoded space character is valid in Windows (I am able to paste this url into file explorer and run the file), it does not seem to be valid in the FFmpeg library you are using.

I have added extra decoding to the urlToString() function to replace %20 with a space character, and this seems to have fixed the issue.

I tested the fix on the main branch.
I also packaged the library into a jar, and added the compiled native libraries to the jar file, and successfully tested it with your other project audioplayer4j.

@Supernova1114
Copy link
Author

It looks like an encoded string in general is not supported by the ffmpeg ff_open_format_context() function for a local file. I have encountered extra FileNotFound errors with other file paths.

I am in the process of writing up a fix.

@Supernova1114 Supernova1114 changed the title Bug Fix: Added URL space character decoding for Windows file paths. Bug Fix: Windows URL Decoding Jan 29, 2025
@Supernova1114
Copy link
Author

FFAudioFileReader reader = new FFAudioFileReader();

String tempStr_1 = "file:///C:/Users/Super/Downloads/temp/temp%20Again/audio.ogg";
URL url_1 = URI.create(tempStr_1).toURL();

String tempStr_2 = "file://CAMERON-NAS/home/Songs/space%20space/audio.mp3";
URL url_2 = URI.create(tempStr_2).toURL();

String file_1 = "\\\\CAMERON-NAS\\home\\Songs\\space space\\audio.mp3"; // creates a "file:////" url

String file_2 = "C:\\Users\\Super\\Downloads\\temp\\temp Again\\audio.ogg";

try {
    System.out.println("URL 1");
    System.out.println("Result: " + reader.getAudioFileFormat(url_1));

    System.out.println("URL 2");
    System.out.println("Result: " + reader.getAudioFileFormat(url_2));

    System.out.println("File 1");
    System.out.println("Result: " + reader.getAudioFileFormat(new File(file_1)));

    System.out.println("File 2");
    System.out.println("Result: " + reader.getAudioFileFormat(new File(file_2)));
} catch (UnsupportedAudioFileException | IOException e) {
    e.printStackTrace();
}
Jan 28, 2025 4:41:13 PM com.tagtraum.ffsampledsp.FFNativeLibraryLoader arch
INFO: Using arch=x86_64
URL 1
Result: OGG (.ogg) file, byte length: 2427072, data format: VORBIS 48000.0 Hz, unknown bits per sample, stereo, unknown frame size, unknown frame rate
URL 2
Result: MP3 (.mp3) file, byte length: 0, data format: MPEG-1, Layer 3 44100.0 Hz, unknown bits per sample, stereo, unknown frame size, 38.28125 frames/second, frame length: 9054
File 1
Result: MP3 (.mp3) file, byte length: 0, data format: MPEG-1, Layer 3 44100.0 Hz, unknown bits per sample, stereo, unknown frame size, 38.28125 frames/second, frame length: 9054
File 2
Result: OGG (.ogg) file, byte length: 2427072, data format: VORBIS 48000.0 Hz, unknown bits per sample, stereo, unknown frame size, unknown frame rate

Process finished with exit code 0

Made a new fix taking into consideration general file URL decoding and tested it with the above code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant