3

I use getDuration on a local MP3file successfully, but when getDuration on a remote MP3stream results in an error: java.io.IOException: mark/reset not supported.

Successful getDuration on local MP3:

 public static void getDurationOff() throws UnsupportedAudioFileException, IOException {
         int sumtime = 0;
         File file = new File("D:\\java\\MusicMP3\\src\\Images\\Water_Lily.mp3");
         AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file);
         if (fileFormat instanceof TAudioFileFormat) {
             Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
             Long microseconds = (Long) properties.get("duration");
                //total seconds
             sumtime = (int)(microseconds / 1000000);
             System.out.println("Total seconds :"+sumtime);
         }
     }

Failed getDuration on remote MP3:

 public static void getDurationOn() throws UnsupportedAudioFileException, IOException {
             int sumtime = 0;
             String linkonline="http://api.mp3.zing.vn/api/mobile/source/song/LmJnykGNlNmnNkuTZvctbGZm";
             URLConnection urlConnection = new URL(linkonline).openConnection();
             urlConnection.connect();
             AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(urlConnection.getInputStream());
             if (fileFormat instanceof TAudioFileFormat) {
                 Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
                 Long microseconds = (Long) properties.get("duration");
                 //total seconds
                 sumtime = (int)(microseconds / 1000000);
                 System.out.println("Total seconds :"+sumtime);
             }
         }

Error:

 Exception in thread "main" java.io.IOException: mark/reset not
 supported  at
 sun.net.www.http.KeepAliveStream.reset(KeepAliveStream.java:122)   at
 java.io.FilterInputStream.reset(FilterInputStream.java:226)    at
 sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.reset(HttpURLConnection.java:3299)
    at
 org.tritonus.share.sampled.file.TAudioFileReader.getAudioFileFormat(TAudioFileReader.java:184)
    at
 javax.sound.sampled.AudioSystem.getAudioFileFormat(AudioSystem.java:1004)
    at musicmp3.demoGetlink.getDurationOn(demoGetlink.java:99)  at
 musicmp3.demoGetlink.main(demoGetlink.java:118) Java Result: 1
cheng
  • 1,196
  • 2
  • 12
  • 16

2 Answers2

1

As the line

javax.sound.sampled.AudioSystem.getAudioFileFormat(AudioSystem.java:1004)

seems to be whats throwing the error according to the stack trace. From the spec of AudioSystem

"The implementation of this method may require multiple parsers to examine the stream to determine whether they support it. These parsers must be able to mark the stream, read enough data to determine whether they support the stream, and, if not, reset the stream's read pointer to its original position."

but you appear to be using the stream type sun.net.www.http.KeepAliveStream which in the source returns False for markSupported(). Try creating a new BufferedInputStream from the returned input stream of getInputStream e.g.

InputStream is = urlConnection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);

And use that.

Edit: typo

Edit2: Whoops just noticed possible duplicate with java.io.IOException: mark/reset not supported

Community
  • 1
  • 1
csunday95
  • 1,279
  • 10
  • 18
  • Thank you for help me,I've tried but return an error : `Exception in thread "main" java.lang.NullPointerException` – cheng May 29 '15 at 19:15
  • Could you give the full stack trace? Where is the error thrown? – csunday95 May 29 '15 at 19:26
  • **Error**:`Exception in thread "main" java.lang.NullPointerException at musicmp3.demoGetlink.getDurationOn(demoGetlink.java:111) at musicmp3.demoGetlink.main(demoGetlink.java:148) Java Result: 1` – cheng May 30 '15 at 04:26
  • **This is code I changed**: `URLConnection urlConnection = new URL(linkonline).openConnection(); InputStream is = urlConnection.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(bis);` – cheng May 30 '15 at 04:29
0

There are three ways to use AudioSystem.getAudioFileFormat(yourParameter). In the non-working code you show, you use an InputStream as your parameter, which can (but not always) trigger mark/reset tests.

Alternatively, you could just use the File or Url as a parameter. This does not trigger mark/reset tests. You use File successfully in your working example. Try using a simple URL as a parameter in the non-working, instead of deriving an InputStream from the URL.

I'm not entirely clear from the error message you show where the error is arising. My apologies if it is from a different section of code. Also, I am not experienced with reading .mp3 files. I usually work with wav. But I have come across the InputStream mark/reset error multiple times.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41