This discussion is archived
7 Replies Latest reply: Nov 28, 2012 2:01 AM by MiPa RSS

Playing mp3 files in JavaFx from input stream

631145 Newbie
Currently Being Moderated
I am using JavaFX media player to play an mp3 file using following code

new MediaPlayer(new Media(FileObject.toURI().toString())).play();

However now I have a requirement that I have the mp3 byte data in memory instead of an File Object. The reason is the mp3 file is encrypted and then shipped along with the program. Hence I need to decrypt the mp3 file in memory or input stream.

I could decrypt the mp3 file to an temporary file in temp directory but this would be a performance overhead and the audio content would be insecure.
  • 1. Re: Playing mp3 files in JavaFx from input stream
    805536 Journeyer
    Currently Being Moderated
    I'm afraid there are no easy solutions. I believe this feature has been requested, but as of the present, JavaFX cannot load media from an InputStream.

    And even if it could, you can't really stop a technically sophisticated person from breaking into your MP3 file anyways. If I were interested in doing such a thing, all I would have to do is decompile your program and rewrite it to output the contents to a file. The best you can do is make it a black box for the general populace.

    The solution you mentioned is the only one available if the audio is to be shipped alongside your program. In which case you may as well store it inside the jar unencrypted. It's not like copying the unencrypted file over to the temp directory is much if any more secure than having an unencrypted file inside the jar.
  • 2. Re: Playing mp3 files in JavaFx from input stream
    James_D Guru
    Currently Being Moderated
    I think there may be a way to do this, though I haven't tried to make it work and I think it might be difficult. The basic idea is that the URL class reads its content from an InputStream which is returned from the method calls openConnection().getInputStream(). So you need to arrange for the openConnection() method to return a URLConnection object whose getInputStream() method returns the InputStream from which you want to read.

    1. Create a subclass of URLConnection which takes a reference to the InputStream. Override the getInputStream() method to return a reference to this InputStream. Implement the connect() method trivially (no-op?). You'll likely need to override some other methods too.

    2. Create a subclass of URLStreamHandler which also takes a reference to an InputStream. Implement the openConnection(...) method to return an instance of the class defined in the previous step, passing on the reference to the InputStream. Again, you'll likely have to override some other methods here.

    3. Construct a URL using the constructor URL(URL context, String spec, URLStreamHandler handler), passing in a reference to your custom URLStreamHandler as the third parameter. You'll need to dig into the javadocs to figure out what to pass in for the other two parameters and how these might tie into the other methods you may need to override in the URLConnection and URLStreamHandler subclasses.

    The comments concerning how secure you really make this are very valid, and you should consider carefully whether this is worth the effort in the light of these. (You'll notice I have not tried to implement any of this ;).)

    Good luck...
  • 3. Re: Playing mp3 files in JavaFx from input stream
    805536 Journeyer
    Currently Being Moderated
    >
    I think there may be a way to do this, though I haven't tried to make it work and I think it might be difficult. The basic idea is that the URL class reads its content from an InputStream which is returned from the method calls openConnection().getInputStream(). So you need to arrange for the openConnection() method to return a URLConnection object whose getInputStream() method returns the InputStream from which you want to read.
    >

    I tried that once. Didn't work. It's been a while (it was done in JavaFX Script), so things might have changed, but even if they have, that is still a hack that is not guaranteed to work between versions.

    If you insist on trying it yourself, the relevant forum thread to the previous attempt is here: JavaFX storage based url handler
  • 4. Re: Playing mp3 files in JavaFx from input stream
    James_D Guru
    Currently Being Moderated
    Yeah, I'll believe it. Don't think I will try to pursue it further at this late hour...
  • 5. Re: Playing mp3 files in JavaFx from input stream
    James_D Guru
    Currently Being Moderated
    I had a closer look at this, just out of curiosity. My idea of creating a custom URLConnection will not work; the javadocs for Media explicitly state that only HTTP, FILE, and JAR protocols are supported, and this is explicitly checked and an exception thrown if you try to use another protocol. I experimented a bit to see if I could hack it by effectively redefining the HTTP or FILE protocol handlers (setting up custom URLStreamHandlers for either one) and this doesn't work either. It actually looks like the JavaFX team have tried quite hard to make it impossible to load media other than by using one of these three protocols. There is likely a good reason for this; maybe a security issue or maybe the implementation of Media or MediaPlayer relies on knowing some specific details about the source of the media.
  • 6. Re: Playing mp3 files in JavaFx from input stream
    not-zed Newbie
    Currently Being Moderated
    You know, it's probably for something rather mundane such as the media libraries implementing their own URL handlers (e.g. in c), and not going through URLConnection.
  • 7. Re: Playing mp3 files in JavaFx from input stream
    MiPa Pro
    Currently Being Moderated
    You might also want to vote for this long standing JIRA feature request:
    http://javafx-jira.kenai.com/browse/RT-14938
    It contains one comment which seems to ask for exactly what you want to do.
    Michael

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points