I'm using JAAD with SPI to play m4a files through JavaSound, which I have working fine.
However, I'd like to support a number of formats in this way - but whenever I try and play another format, JAAD seems to try to deal with it and then fail (obviously because it only deals with AAC.)
I'm assuming this is a bug in JAAD, since all the other SPI libraries play fine with each other. Is there a nice way to work around it until it's fixed, or is there another AAC library that works with Javasound which I can use?
There is a workaround using jaad created by Michael Berry: this is the url
https://code.google.com/p/quelea-projection/source/browse/Quelea/src/org/quelea/sound/AudioTrack.java?spec=svn0352523f49cf20d41d1a7dc098af1db38000cc6d&r=0352523f49cf20d41d1a7dc098af1db38000cc6d
Since it took me a while to find berry150's code, here is the solution:
First, you have to order the jars in the classpath so that JLayer, MP3SPI and Tritonous Share are loaded before JAAD. Then for getting the AudioInputStream, use the following code:
if (getAudioFormat().equals(".mp3")) {
audioStream = AudioSystem.getAudioInputStream(file); // Obtains an audio input stream of the song
}
else if (getAudioFormat().equals(".m4a")){
audioStream = new AACAudioFileReader().getAudioInputStream(file);
}
So what happens is that if the audio is mp3, the getAudioStreamMethod() from Javasound will be called first since its JAR was loaded first. If the audio is .m4a, a new instance of the ACCAudioFileReader() is created and the getAudioInputStream() of the JAAD library is called.
Related
Trying to build a little app for sorting through audio files based on some of their properties. Have managed to grab the Sample Rate and Bit Depth using Minim but can't find anything anywhere for getting the Bit Rate?
Happy to look at taking the program to Javascript if needed but just desperate to find a method for detecting bit rate of a given file.
EDIT: Attempted to try and form an equation based off file size but cannot find a method for detecting MP3 file size either.
You can use jaudiotagger
You will need to download the jar, I managed to get it from maven central
Go to Sketch -> Add File... and select the downloaded jar, it should be added in a folder named code within your sketch folder.
Assuming you have placed an mp3 file in your data folder named audio.mp3 the following code should work, printing out the bit rate in the terminal.
import org.jaudiotagger.audio.mp3.*;
import org.jaudiotagger.audio.AudioFileIO;
void setup() {
File f = new File(dataPath("audio.mp3"));
try {
MP3File mp3 = (MP3File) AudioFileIO.read(f);
MP3AudioHeader audioHeader = mp3.getMP3AudioHeader();
println("" + audioHeader.getBitRate());
}
catch(Exception e) {
e.printStackTrace();
}
}
JAudiotagger supports a variety of file formats and you can use the relevant classes and methods for each one of these.
I suggest you take a look at the javadoc. Be careful of the examples though, the one I used in order to answer your question seems to be faulty, as you can see I had to swap getAudioHeader with getMP3AudioHeader.
I was wondering if there is a way to access a file and it's path from my assets folder in android studio? The reason why I need to access the file and its path is because I am working with a method that REQUIRES the String path for a file, and it must access the file from its String path. However, in android studio I haven't found a way to access the file directly from the String value of its path. I decided to use a workaround and simply read the file from an InputStream and write the file to an OutputStream, but the file is about 170MB, and it is too memory intensive to write the File to an OutputStream. It takes my application about 10:00 Minutes to download the file when I implement that strategy. I have searched all over this website and numerous sources to find a solution (books and documentation) but am unable to find a viable solution. Here is an example of my code:
#Override
public Model doInBackground(String... params){
try {
String filePath = context.getFilesDir() + File.separator + "my_turtle.ttl";
File destinationFile = new File(filePath);
FileOutputStream outputStream = new FileOutputStream(destinationFile);
AssetManager assetManager = context.getAssets();
InputStream inputStream = assetManager.open("sample_3.ttl");
byte[] buffer = new byte[10000000];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
model = ModelFactory.createDefaultModel();
TDBLoader.loadModel(model, filePath, false);//THIS METHOD REQUIRES THE FILE PATH.
MainActivity.presenter.setModel(model);
}catch(FileNotFoundException e){
e.printStackTrace(System.out);
}
catch(IOException e){
e.printStackTrace(System.out);
}
return model;
}
As you can see the TDBLoader.loadModel() method requires a String for the file URI as the second argument, so it would be convenient to have the ability to access the File directly from my assets folder without utilizing an InputStream. The method takes as an argument (Model model, String url, Boolean showProgress). As I mentioned, the current strategy I am using utilizes too much memory and either crashes the Application entirely, or takes 10 minutes to download the file I need. I am using an AsyncTask to perform this operation, but due to the length of time required to perform the task that kind of defeats the purpose of an AsyncTask in this scenario.
What further complicates things is that I have to use an old version of Apache Jena because I am working with Android Studio and the official version of Apache Jena is not compatible with android studio. So I have to use a port that is 8 years old which doesn't have the updated classes that Apache Jena offers. If I could use the RDFParser class I could pass an InputStream, but that class does not exist in the older version of Apache Jena that I must use.
So I am stuck at this point. The method must utilize the String url path of the file in my assets folder, but I don't know how to access this without writing to a custom file from an InputStream, but writing to the file from the InputStream utilizes too much memory and forces the App to crash. If anyone has a solution I will greatly appreciate it.
Here is an example of my code
new byte[10000000] may fail, as you may not have a single contiguous block of memory that big. Plus, you might not have that much heap space to begin with. Use a smaller number, such as 65536.
It takes my application about 10:00 Minutes to download the file when I implement that strategy
The time will vary by hardware. I would not expect it to be that slow on most devices, but it could be on some.
I was wondering if there is a way to access a file and it's path from my assets folder in android studio?
You are running your app on Android. Android Studio is not running on Android. Assets are not files on the Android device. They are entries in the APK file, which is basically a ZIP archive. In effect, your code is unZIPping 170MB of material and writing it out to a file.
If anyone has a solution I will greatly appreciate it.
Work with some people to port over an updated version of Jena that offers reading RDF from an InputStream.
Or switch to some other RDF library.
Or work with the RDF file format directly.
Or use a smaller RDF file, so the copy takes less time.
Or download the RDF file, if you think that will be preferable to copying over the asset.
Or do the asset-to-file copying in a foreground JobIntentService, updating the progress in its associated Notification, so that the user can do other things on their device while you complete the copy.
I've been struggling with this for a while now and I decided it was time I needed to ask for help.
So basically IVONA is a TTS(text-to-speech) service that has a way of using it in Java with a key(which I have).
Though, there is a sample class that they give you, Link to Sample Class . Which shows you how to use the API and save it as an MP3.
I'm asking how would I modify this class to rather than saving the MP3 it reads, how can I make it so it plays it via Clips and AudioSystem's.
I appreciate all and any responses, thank you very much!
InputStream is = null;//Actual InputStream here
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(is));
clip.start();
I want just to perform a simple task. (I'm a java newbie). I want to play an audio clip when a button is clicked.
here's the part of my code(which I did exactly by copying a tutorial from Youtube.)
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {
InputStream in;
try{
in=new FileInputStream(new File("C:\\Users\\Matt\\Documents\\dong.wav"));
AudioStream timeupsound=new AudioStream(in);
AudioPlayer.player.start(timeupsound);
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
But the problem is, this doesn't work.
It throws and IOException saying: "could not create audio stream from input stream".
My question is, what am I doing wrong? (as I clearly saw this code work in that youtube video, and I've used the same code. Please help. and once again, I'm a newbie);
The sun package classes should be causing some informative warnings at compile time. Heed them. Don't use classes in that package hierarchy. They are undocumented, are not guaranteed from one Java version to the next, and will probably not be available in a non-Oracle JRE at all.
Instead use the Java Sound based Clip to play audio. See the info. page for working examples.
Note
It might be the WAV is encoded in a format that Java Sound does not support. Media formats are typically 'container formats' that might be encoded using any number of different Codecs. It is likely that WAV is using a more compressive Codec such as MP3 or OGG internally.
I don't know of a Service Provider Interface for the OGG format, but if they are encoded as MP3, you might be able to get it working using the MP3 SPI. See the info. page linked above for details.
Tip
Also change code of the form:
catch (Exception e) { ..
To
catch (Exception e) {
e.printStackTrace(); // very informative! ...
I am trying to run a sound file in Java using this code:
public class Audio3
{
public static void main(String[] args) throws Exception
{
URL soundFile =new URL(
"http://everyayah.com/data/Ghamadi_40kbps/audhubillah.mp3");
AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
AudioPlayer.player.start(ais);
}
}
I am getting this exception
javax.sound.sampled.UnsupportedAudioFileException:
could not get audio input stream from input URL
Any idea what could be the reason?
According to the JavaSound info. page.
MP3 decoding support
The Java Sound API does not support many formats of sampled sound internally. In a 1.6.0_24 Oracle JRE getAudioFileTypes() will generally return {WAVE, AU, AIFF}. An MP3 decoder at least, is close by. The mp3plugin.jar of the Java Media Framework supports decoding MP3s.
I can vouch for that information since I've successfully loaded MP3s using Java Sound and the MP3 SPI (& also wrote the info. page ;) ). The JMF installer download is becoming hard to find, but you can get the mp3plugin.jar direct from where I put it for use in JWS apps.