Download and Play Remote Media Files

199 views
Skip to first unread message

dansp...@gmail.com

unread,
Apr 29, 2014, 2:51:04 AM4/29/14
to codenameone...@googlegroups.com, Dan Spiegel
My app needs to download media files (images, audio and video) from an arbitrary URL, store them locally and then play them back through the MediaPlayer.  I need to give my app users access to play controls (Forward, Back, Play).  

I have a URL that will force a download of a media file when accessed through a desktop-based Web browser.  But, I need to know two things:

  1. How do I make my codenameone app download the files and store them locally?  (Using CodenameOne's hosted files option is not going to work because these aren't my files.  They are hosted by someone else.)  The storage access code I see in the demos seems to only be for text files and they do not provide instruction for downloading binaries from a Website.
    Storage.getInstance().writeObject("myStore", p);  //where p is a vector

  2. Once the files are downloaded to local storage, how do I reference them so that I can play them through the media player?  I am not sure where these files will end up relative to my app.  (I think if you use the Storage option, you don't need to worry about where they go, you just request them by name.)

I figure the code I need to play the files through the MediaPlayer must be some variant of what is in the KitchenSink demo.  The KitchenSink demo works file for me for the locally stored video file that came with that demo.  But, I am not sure how to adapt it to download files and access those files from local storage.

Here is the code from the KitchenSink demo:

String requestString = "[SOME PATH.... BUT, WHERE?]";

Container player = new Container(new BorderLayout());
final MediaPlayer mp = new MediaPlayer();
try {
        mp.setDataSource(requestString);
} catch (Exception ex) {
    ex.printStackTrace();
}
player.addComponent(BorderLayout.CENTER, mp);


Shai Almog

unread,
Apr 29, 2014, 2:02:43 PM4/29/14
to codenameone...@googlegroups.com, Dan Spiegel
For working with media you will need to use FileSystemStorage and download the files to the home directory mentioned there.
You can accomplish that more easily by using Util.downloadUrlToFile().
Then you can play a the media from the file URL.

dansp...@gmail.com

unread,
Apr 30, 2014, 8:18:14 AM4/30/14
to codenameone...@googlegroups.com, Dan Spiegel
Thanks, Shai.  I am able to download my file to local storage.  But, I get Null Pointer Exception when I try to access it.

This displays true.
System.out.println( FileSystemStorage.getInstance().exists(FileSystemStorage.getInstance().getAppHomePath() + fileName));

I see the file I downloaded on my hard drive here: C:\Users\Dan\.cn1\mysound.mp3.

But, these three access methods return Null Pointer Exception:

InputStream is = Display.getInstance().getResourceAsStream(getClass(),  FileSystemStorage.getInstance().getAppHomePath() + fileName);
mp.setDataSource(is, "audio/mp3", null);

mp.setDataSource(FileSystemStorage.getInstance().getAppHomePath() + fileName);

mp.setDataSource("/mysound.mp3");

Any idea what I am doing wrong?

Shai Almog

unread,
Apr 30, 2014, 12:50:37 PM4/30/14
to codenameone...@googlegroups.com, Dan Spiegel
The second setDataSource should work. What is the stack of the exception you got?

dansp...@gmail.com

unread,
Apr 30, 2014, 11:15:52 PM4/30/14
to codenameone...@googlegroups.com, Dan Spiegel
Hi Shai,

Here is the stack trace:
java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at javafx.scene.media.Media.<init>(Media.java:359)
at com.codename1.impl.javase.JavaSEPort$CodenameOneMediaPlayer.<init>(JavaSEPort.java:5145)
at com.codename1.impl.javase.JavaSEPort$43.run(JavaSEPort.java:4120)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at java.net.URI$Parser.fail(Unknown Source)
at java.net.URI$Parser.checkChars(Unknown Source)
at java.net.URI$Parser.parse(Unknown Source)
at java.net.URI.<init>(Unknown Source)
at javafx.scene.media.Media.<init>(Media.java:357)
... 7 more
java.io.IOException: java.lang.RuntimeException: java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at com.codename1.impl.javase.JavaSEPort.createMedia(JavaSEPort.java:4140)
at com.codename1.ui.Display.createMedia(Display.java:2751)
at com.codename1.media.MediaManager.createMedia(MediaManager.java:80)
at com.codename1.components.MediaPlayer.setDataSource(MediaPlayer.java:149)
at com.codename1.components.MediaPlayer$1.run(MediaPlayer.java:166)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at com.codename1.impl.javase.JavaSEPort$CodenameOneMediaPlayer.<init>(JavaSEPort.java:5153)
at com.codename1.impl.javase.JavaSEPort$43.run(JavaSEPort.java:4120)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at javafx.scene.media.Media.<init>(Media.java:359)
at com.codename1.impl.javase.JavaSEPort$CodenameOneMediaPlayer.<init>(JavaSEPort.java:5145)
... 6 more
Caused by: java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\Dan\.cn1\mysound.mp3
at java.net.URI$Parser.fail(Unknown Source)
at java.net.URI$Parser.checkChars(Unknown Source)
at java.net.URI$Parser.parse(Unknown Source)
at java.net.URI.<init>(Unknown Source)
at javafx.scene.media.Media.<init>(Media.java:357)
... 7 more

I see what looks like a related issue that you indicated you were working on.  Search the forum for ": Illegal character in opaque part at index 2:"

-Dan

Shai Almog

unread,
May 1, 2014, 12:57:13 AM5/1/14
to codenameone...@googlegroups.com, Dan Spiegel
Hi,
I think this is a known regression in the current simulator and I think its already fixed in SVN. It should be supported for the next update.
As a short term workaround you can use the FileSystemStorage to get an InputStream and pass that to the media. You should just do that for now since its more wasteful than passing the URL.

Dan Spiegel

unread,
May 1, 2014, 8:04:30 AM5/1/14
to Shai Almog, codenameone...@googlegroups.com
Hi Shai,

Thanks for the prompt responses.  

Are you suggesting the following approach?
InputStream is = Display.getInstance().getResourceAsStream(getClass(),  FileSystemStorage.getInstance().getAppHomePath() + fileName);

mp.setDataSource(is, "audio/mp3", null);


This approach results in the following exception: 

ERROR: resources must reside in the root directory thus must start with a '/' character in Codename One! Invalid resource: file://home/mysound.mp3
java.io.IOException: java.lang.NullPointerException
at com.codename1.impl.javase.JavaSEPort.createMedia(JavaSEPort.java:4200)
at com.codename1.ui.Display.createMedia(Display.java:2766)
at com.codename1.media.MediaManager.createMedia(MediaManager.java:96)
at com.codename1.components.MediaPlayer.setDataSource(MediaPlayer.java:193)
at com.payzow.components.Newsfeed$1$3.actionPerformed(Newsfeed.java:268)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:345)
at com.codename1.ui.Button.fireActionEvent(Button.java:386)
at com.codename1.ui.Button.released(Button.java:417)
at com.codename1.ui.Button.pointerReleased(Button.java:505)
at com.codename1.ui.Form.pointerReleased(Form.java:2318)
at com.codename1.ui.Dialog.pointerReleased(Dialog.java:1691)
at com.codename1.ui.Form.pointerReleased(Form.java:2258)
at com.codename1.ui.Dialog.pointerReleased(Dialog.java:1691)
at com.codename1.ui.Component.pointerReleased(Component.java:2352)
at com.codename1.ui.Display.handleEvent(Display.java:1892)
at com.codename1.ui.Display.edtLoopImpl(Display.java:994)
at com.codename1.ui.Display.invokeAndBlock(Display.java:1129)
at com.codename1.ui.Display.invokeAndBlock(Display.java:1164)
at com.codename1.ui.Form.showModal(Form.java:1531)
at com.codename1.ui.Dialog.showModal(Dialog.java:1085)
at com.codename1.ui.Dialog.show(Dialog.java:466)
at com.codename1.ui.Dialog.showPackedImpl(Dialog.java:1362)
at com.codename1.ui.Dialog.showPacked(Dialog.java:1273)
at com.codename1.ui.Dialog.showImpl(Dialog.java:1045)
at com.codename1.ui.Dialog.show(Dialog.java:1027)
at com.payzow.components.Newsfeed$1.actionPerformed(Newsfeed.java:305)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:345)
at com.codename1.ui.Button.fireActionEvent(Button.java:386)
at com.codename1.ui.Button.released(Button.java:417)
at com.codename1.ui.Button.pointerReleased(Button.java:505)
at com.codename1.ui.Form.pointerReleased(Form.java:2318)
at com.codename1.ui.Form.pointerReleased(Form.java:2258)
at com.codename1.ui.Component.pointerReleased(Component.java:2352)
at com.codename1.ui.Display.handleEvent(Display.java:1892)
at com.codename1.ui.Display.edtLoopImpl(Display.java:994)
at com.codename1.ui.Display.mainEDTLoop(Display.java:925)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Caused by: java.lang.NullPointerException
at com.codename1.impl.javase.JavaSEPort$CodenameOneMediaPlayer.<init>(JavaSEPort.java:5185)
at com.codename1.impl.javase.JavaSEPort$45.run(JavaSEPort.java:4180)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Unknown Source)

-Dan


On Wed, Apr 30, 2014 at 12:50 PM, Shai Almog <shai....@gmail.com> wrote:
The second setDataSource should work. What is the stack of the exception you got?



--

 

Sincerely,
Dan Spiegel, PMP
631.219.6710
Skype: danspiegel.thrive

Shai Almog

unread,
May 1, 2014, 2:04:45 PM5/1/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
Hi,
not getResourceAsStream. That method is only for resources (files shipped in the "jar"). Use: FileSystemStorage.openInputStream()

dansp...@gmail.com

unread,
May 4, 2014, 12:46:48 AM5/4/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
Hi Shai,

Using your suggested approach, audio files play in the media player.  But, video files do not.  The media player displays.  But, when I press play, nothing happens.  I have tried an avi file and the mp4 file from the Kitchen Sink demo. This mp4 file works perfectly in the Kitchen Sink demo where it is accessed via  Display.getInstance().getResourceAsStream().

Here is my code:

InputStream is = FileSystemStorage.getInstance().openInputStream(FileSystemStorage.getInstance().getAppHomePath() + "/video.mp4");
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(is, "video/mp4", null);
} catch (Exception ex) {
ex.printStackTrace();
} //try

-Dan

Shai Almog

unread,
May 4, 2014, 12:57:51 AM5/4/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
Hi,
do you get an exception? Do you have the stack?
Is the file there? Is it valid?

Dan Spiegel

unread,
May 4, 2014, 11:52:20 AM5/4/14
to Shai Almog, codenameone...@googlegroups.com, Shai Almog
No exception. The file is there and valid. It plays fine through Windows Media Player.

Thanks,
Dan Spiegel, PMP
(631) 219-6710 c

Shai Almog

unread,
May 4, 2014, 2:18:21 PM5/4/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
Did you place the MediaPlayer on the form?
In which layout?

Dan Spiegel

unread,
May 4, 2014, 2:43:13 PM5/4/14
to Shai Almog, codenameone...@googlegroups.com, Shai Almog
I put it in a dialog in a container that was in BorderLayout.

Thanks,
Dan Spiegel, PMP
(631) 219-6710 c

Shai Almog

unread,
May 5, 2014, 1:11:21 AM5/5/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
I suggest putting it in a form with the same layout. I'm assuming you get a really small dialog that doesn't have room to show the media, right?

Dan Spiegel

unread,
May 6, 2014, 12:02:53 AM5/6/14
to Shai Almog, codenameone...@googlegroups.com
Hi Shai,

I put the media player in a form inside a container that was in BorderLayout.  I am getting the same result.  I see "Back play fwd" and nothing else.  If I press "play," it turns to "p..." and nothing further happens.  There is no exception.

The file type is set to "video/mp4" as it is supposed to be according to this post:

Here is my code:

btnViewMediaFile.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
final Form viewMedaForm = new Form();
              Layout layout = new BorderLayout();
              Container container = new Container(layout);
              viewMedaForm.addComponent(container);
              if (fileType.startsWith("image"))
              {
              @SuppressWarnings("deprecation")
String path = (String)FileSystemStorage.getInstance().getAppHomePath() + "/" + fileName;
              try {
Image myImage =  Image.createImage(path);
Label l = new Label();
l.setIcon(myImage);
container.addComponent(BorderLayout.CENTER, l);
} catch (IOException e) {
Dialog.show("Image Broken", "The file " + fileName + " does not open properly.", "OK", "");
e.printStackTrace();
}
              } else {
final MediaPlayer mp = new MediaPlayer();
try {
InputStream is = FileSystemStorage.getInstance().openInputStream(FileSystemStorage.getInstance().getAppHomePath() + "/" + fileName);
mp.setDataSource(is, fileType, null);
mp.getMedia().setFullScreen(true);
container.addComponent(BorderLayout.CENTER, mp);
} catch (Exception ex) {
Dialog.show("Video Broken", "The file " + fileName + " does not open properly.", "OK", "");
ex.printStackTrace();
} //try
              } //if
              Button btnClose = new Button("Close");
btnClose.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent ev){
    Session.getCurrentForm().show();
    } //actionPerformed
});
container.addComponent(BorderLayout.SOUTH,btnClose);
viewMedaForm.show();
        }//actionPerformed
});
ctr.addComponent(btnViewMediaFile);


On Mon, May 5, 2014 at 1:11 AM, Shai Almog <shai....@gmail.com> wrote:
I suggest putting it in a form with the same layout. I'm assuming you get a really small dialog that doesn't have room to show the media, right?



Shai Almog

unread,
May 6, 2014, 2:07:39 AM5/6/14
to codenameone...@googlegroups.com, Shai Almog, dansp...@gmail.com
Hi,
viewMedaForm defaults to flow layout which makes the border layout in the container within meaningless.
Try viewMedaForm.setLayout(new BorderLayout());

Then either add the media stuff directly to the form or add your container like this:
viewMedaForm.addComponent(BorderLayout.CENTER, container);
Reply all
Reply to author
Forward
0 new messages