I have a problem with playing an MP3 file with JMF, it displays the following error :
Error:
Unable to realize com.sun.media.amovie.AMController#80669d Exception in thread "main"
javax.media.CannotRealizeException at javax.media.Manager.blockingCall(Manager.java:2005) at
javax.media.Manager.createRealizedPlayer(Manager.java:528) at tp.Main.main(Main.java:44)
Error value: 80070020
here is my code :
public class Main {
public static void main(String[] args) throws NoPlayerException, CannotRealizeException, MalformedURLException, IOException, URISyntaxException {
Fenetre F1 = new Fenetre();
F1.setVisible(true);
InputStream is = Main.class.getClass().getResourceAsStream("/data/gmu.mp3");
File temp=File.createTempFile("temp", ".mp3");
OutputStream os = new FileOutputStream(temp);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
final Player p=Manager.createRealizedPlayer(temp.toURI().toURL());
p.start();
while(true){
if(p.getMediaTime().getSeconds()==p.getDuration().getSeconds()){
p.stop();
p.setMediaTime(new Time(0));
p.start();
}
}
}
}
normally it works If I don't use the InputStream, and use simply
File f =new File(Main.class.getResource("/data/gmu.mp3").getFile());
final Player p=Manager.createRealizedPlayer(temp.toURI().toURL());
but this way It doesn't work when I pack my JAR file, so I'm trying to use InputStream, the aim is to make a JAR with a WORKING music
Actually I just had to convert my MP3 file to WAV and it worked !!! I don't know why the player exception was caught with the MP3 temporary file but nothing goes wrong with WAV. this is not really the answer I sought since the WAV files takes a lot more space but at least it works.
I also tried OGG format, which makes the same problem of MP3 ...
any other answer, suggestion, or discussion is welcome.
Related
i try to copy mp3 file in external storage and limit duration of new file. it work but when it started, although i run to limit time, it still display end time like old file.
private void copy(File in, File out) throws IOException {
FileInputStream is = null;
FileOutputStream os = null;
try {
is = new FileInputStream(in);
os = new FileOutputStream(out);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0 && out.length()<175642) {
os.write(buffer, 0, length);
}
} finally {
assert is != null;
is.close();
assert os != null;
os.close();
}
}
how can i fix it. i really expect your help. have a nice day,everyone!
You simply cut of the rest of the file. This leads to a kind of corrupted file because the data in the header-block (e.g. the length) is no longer correct.
For some information about the mp3 file format:
https://en.wikipedia.org/wiki/MP3
I highly recommend to adjust the header information after shortening the file.
I'm writing a program part simply to copy a file from source to a destination File. The code works as well it should but if there is a file large file the process of copy will end up, after the destination file reach a size of 4.3 GB, with an exception. The exception is a "file is to large" it looks like:
java.io.IOException: Die Datei ist zu groß
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:211)
at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
at java.nio.channels.Channels.writeFully(Channels.java:101)
at java.nio.channels.Channels.access$000(Channels.java:61)
at java.nio.channels.Channels$1.write(Channels.java:174)
at java.nio.file.Files.copy(Files.java:2909)
at java.nio.file.Files.copy(Files.java:3069)
at sample.Controller.copyStream(Controller.java:318)
The method to produce that is following:
private void copyStream(File src, File dest){
try {
FileInputStream fis = new FileInputStream(src);
OutputStream newFos = java.nio.file.Files.newOutputStream(dest.toPath(),StandardOpenOption.WRITE);
Files.copy(src.toPath(),newFos);
newFos.flush();
newFos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I also tried to use java.io Fileoutputstream and write in a kbyte way, but there happends the same. How can I copy or create files larger than 4.3 GB? Is it maybe possible in other language than java? This programm I run on a Linux (Ubuntu LTS 16.04).
Thanks in advance.
Edit:
Thanks very much you all for your help. As you said, the file system was the problem. After i formated the file system to exfat it works fine.
POSIX (and thus Unix) systems are allowed to impose a maximum length on the path (what you get from File.getPath() or the components of a path (the last of which you can get with File.getName()). You might be seeing this problem because of the long name for the file.
In that case, the file open operating system call will fail with an ENAMETOOLONG error code.
However, the message "File too large" is typically associated with the ´EFBIG´ error code. That is more likely to result from a write system call:
An attempt was made to write a file that exceeds the implementation-dependent maximum file size or the process' file size limit.
Perhaps the file is being opened for appending, and the implied lseek to the end of the file is giving the EFBIG error.
In the end, you could try other methods of copying if it has to do something with your RAM.
Also another option could be that the disk is full.
To copy files there are basically four ways [and it turns out streams is the fastest on a basic level] :
Copy with streams:
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
Copy with Java NIO classes:
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
Copy with Apache Commons IO FileUtils:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
and your Method by using Java 7 and the Files class:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
Edit 1:
as suggested in the comments, here are three SO-questions, which cover the problem and explain the four different methodes of copying better:
Standard concise way to copy a file in Java?
File copy/move methods and approaches explanation, comparison
Reading and writing a large file using Java NIO
Thanks to #jww for pointing it out
I'm trying to write a file from an AudioInputStream. The stream can read the original file just fine (as far as I can tell). But when it tries to write, it writes what should be a 15 KB file in 44 bytes. Windows Media Player gives the error "either the file type is unsupported, or WMP doesn't recognize the codec used to convert the file."
I got most of this code from http://docs.oracle.com/javase/tutorial/sound/converters.html. I've looked all over StackOverflow but nothing seemed to pertain to this problem.
I've tried getting the format of the AudioInputStream and it's definitely a .wav. As far as I can tell, a codec is software that converts analog to digital data, and both the wav file and the AudioInputStream are digital already.
EDIT: It looks like the stream is writing the WAVE file header to my new file, but nothing else. That's where my 44 byte file is coming from.
Here's the code. I think the problem is in writeFile() but I included the rest just in case:
public static void getFile()
{
try
{
File test = new File("C:\\Users\\Audrey\\Steganography\\correctamundo.wav"); //file to be written from
AudioInputStream stream = AudioSystem.getAudioInputStream(test);
AudioFileFormat format = AudioSystem.getAudioFileFormat(test);
int bytesPerFrame = stream.getFormat().getFrameSize();
byte[] b = new byte[30000]; //array of arbitrary size to hold the bytes in stream
if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) //not sure why this is necessary
{
bytesPerFrame = 1;
}
int i = 0;
while(stream.available() > 0)
{
byte currentByte = (byte)stream.read();
b[i] = currentByte; //read bytes to array
System.out.println(b[i] + " " +(i+1)); //test statement
i++;
}
writeFile(format, stream);
} catch (IOException | UnsupportedAudioFileException e)
{
e.printStackTrace();
}
}
public static void writeFile (AudioFileFormat format, AudioInputStream stream) //format and stream created in getFile() under the same names
{
try
{
File fileOut = new File("C:\\Users\\Audrey\\Steganography\\testFile2.wav");
AudioFileFormat.Type fileType = format.getType(); //type of file the AudioInputStream can write to, since format refers to stream
if (AudioSystem.isFileTypeSupported(fileType, stream))
{
AudioSystem.write(stream, fileType, fileOut);
System.out.println(stream.getFrameLength()); //test statement
}
System.out.println(fileType); //test statement
}
catch (IOException e)
{
e.printStackTrace();
}
}
This question already has an answer here:
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file when loading wav file
(1 answer)
Closed 4 years ago.
I'm trying to add sound to my java game...
I'm playing Sultans of swing at runtime:
static String WHOOSH = "res/WHOOSH.WAV";
static String SULTANS = "res/DireStraits_SultansOfSwing.wav";
music(SULTANS, true);
And this whoosh sound when the ball hits a paddle
music(WHOOSH, false);
public void music(String path, Boolean loop) {
try {
//will go into file folder and get music file (getResource)
AudioInputStream audio = AudioSystem.getAudioInputStream(GamePanel.class.getResource(path));
Clip clip = AudioSystem.getClip();
clip.open(audio);
clip.start();
if (loop) {
clip.loop(1000);
}
}
catch (Exception e) {
System.out.println("Check: " + path + "\n");
e.printStackTrace();
}
}
Problem:
The "Whoosh" always works, but Sultans of Swing does not. Sultans gives me this "Unsupported Audio File Exception" error, which oracle docs tells me
An UnsupportedAudioFileException is an exception indicating that an operation failed because a file did not contain valid data of a recognized file type and format.
Error:
Check: res/DireStraits_SultansOfSwing.wav
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input URL at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
But you can see from these photos that they're both .wav files...
Why is it throwing that error? Is it a size issue?
Thanks!
When I've used wav files for a game, I've done something like this (I've updated it with your path):
public void endingSound() throws IOException{
ClassLoader cl = this.getClass().getClassLoader();
InputStream failSound = cl.getResourceAsStream("res/DireStraits_SultansOfSwing.wav");
if (failSound != null){
AudioStream as = new AudioStream(failSound);
AudioPlayer.player.start(as);
}
else{
System.err.println("cannot load ending sound");
}
}
In this way I assure you won't have any problems when you will export as jar. If is still doesn't work try to rename or replace that file; it may be corrupted as #MadProgrammer said.
Given an InputStream called in which contains audio data in a compressed format (such as MP3 or OGG), I wish to create a byte array containing a WAV conversion of the input data. Unfortunately, if you try to do this, JavaSound hands you the following error:
java.io.IOException: stream length not specified
I managed to get it to work by writing the wav to a temporary file, then reading it back in, as shown below:
AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024));
AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm);
File tempFile = File.createTempFile("wav", "tmp");
AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile);
// The fileToByteArray() method reads the file
// into a byte array; omitted for brevity
byte[] bytes = fileToByteArray(tempFile);
tempFile.delete();
return bytes;
This is obviously less desirable. Is there a better way?
The problem is that the most AudioFileWriters need to know the file size in advance if writing to an OutputStream. Because you can't provide this, it always fails. Unfortunatly, the default Java sound API implementation doesn't have any alternatives.
But you can try using the AudioOutputStream architecture from the Tritonus plugins (Tritonus is an open source implementation of the Java sound API): http://tritonus.org/plugins.html
I notice this one was asked very long time ago. In case any new person (using Java 7 and above) found this thread, note there is a better new way doing it via Files.readAllBytes API. See:
How to convert .wav file into byte array?
Too late, I know, but I was needed this, so this is my two cents on the topic.
public void UploadFiles(String fileName, byte[] bFile)
{
String uploadedFileLocation = "c:\\";
AudioInputStream source;
AudioInputStream pcm;
InputStream b_in = new ByteArrayInputStream(bFile);
source = AudioSystem.getAudioInputStream(new BufferedInputStream(b_in));
pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
File newFile = new File(uploadedFileLocation + fileName);
AudioSystem.write(pcm, Type.WAVE, newFile);
source.close();
pcm.close();
}
The issue is easy to solve if you prepare class which will create correct header for you. In my example Example how to read audio input in wav buffer data goes in some buffer, after that I create header and have wav file in the buffer. No need in additional libraries. Just copy the code from my example.
Example how to use class which creates correct header in the buffer array:
public void run() {
try {
writer = new NewWaveWriter(44100);
byte[]buffer = new byte[256];
int res = 0;
while((res = m_audioInputStream.read(buffer)) > 0) {
writer.write(buffer, 0, res);
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
public byte[]getResult() throws IOException {
return writer.getByteBuffer();
}
And class NewWaveWriter you can find under my link.
This is very simple...
File f = new File(exportFileName+".tmp");
File f2 = new File(exportFileName);
long l = f.length();
FileInputStream fi = new FileInputStream(f);
AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4);
AudioSystem.write(ai, Type.WAVE, f2);
fi.close();
f.delete();
The .tmp file is a RAW audio file, the result is a WAV file with header.