How to Create a Movie Player (Step 2: Adding the Movie Player to NetBeans IDE)

At the end of my recent blog entry "Watch Movies in NetBeans", there are some interesting comments, specifically from Stefan Flemming and Oliver Rettig. Both have very interesting scenarios in which JMF on the NetBeans Platform might be useful to explore. Stefan writes:

"Have you thought about video streaming? Is it possible? It would be so great if i could stream my camera view of the scientific instrument directly into my Netbeans RCP control suite."

And Oliver's use case is:

"I am working with motion anlysis in my docoral research in the gaitlab Heidelberg. I have included my modelling and data analysis sofware in Netbeans and it will be great if can also look at the row patient video also inside netbeans."

The case of streaming, suggested by Stefan, should be possible, since JMF seems to support that (click here). I'd like to experiment with it, but don't know exactly what I would need to have or set up in order to try it out. I mean, what would be a scenario that I could play with easily? In Oliver's scenario, if I follow it correctly, one would have a database with videos, which one would like to see in one's application on the NetBeans Platform. That's completely doable, depending on whether JMF supports the video's format (i.e., file type). And, if it doesn't (such as in the case of the movie format that I make use of), you'd need to get some extra library (like Fobs or FFmpeg).

In both cases, I highly recommend following the instructions in How to Create a Movie Player (Step 1: Setting Up and Testing JMF). In that blog entry, there are two sets of instructions. In the first, you install and configure all the libraries you need. You then open a movie (or whatever you want to play) in the JMF application "JM Studio". Once your application works in there, you build a very simple Java application that results in a Swing movie player. Once your application is playing correctly in that simple application, you're making very good progress. You will possibly have a lot less hair at that stage, or the hair that you had at the start will have gone grey, because of frustrations with JMF, but... if you get that application to work, you're very far along in your journey to movie integration with the NetBeans Platform.

At this point, having overcome various obstacles, you run the application, see a file chooser, select a movie, and then the movie begins in the movie player:

Now click the small button on the right bottom corner of the player. You now see the "Media Properties" application, thanks to JMF. In the "Plug-in Settings" tab, click "PlugIn Viewer". Now you see this:

The above tells you (a) whether both audio and visual are working and (b) which decoders (registered either automatically by the JMF installer or manually by you, when you configured your own additions to JMF, such as Fobs or FFmpeg) are being used. For me, the strange thing is that I see different decoders in use at different times, which tells me that I have several decoders available for the same movie format, and that for whatever reason, sometimes one and sometimes another of my decoders is chosen. So, we need to investigate in the JMF Registry. When I do that, I notice that the decoder that I registered was right at the bottom, so I move it to the top:

Tip: Always click "Commit", otherwise your changes will not be saved!

And now look at the quality of the visual component, much better than before (which tells me that in this instance, you can't provide everything to your end users via NetBeans modules in an update center; quite a few things need to be defined by the end users themselves, on their own system):

And, yes, my self-installed decoder is used instead of the default provided by JMF:

However, now that our Swing application is running so nicely, you want to go one step further -- integrate the functionality into NetBeans IDE. This is really simple. But one principle is important (in general, when porting an application to the NetBeans Platform or any other platform). Do you want to replicate you existing application or do you want to leverage the platform? For example, currently our application consists of a file chooser and a JPanel. When we move the application to a NetBeans module and install it into the IDE, there is no need for a file chooser, because the IDE's Favorites window serves the same purpose. We'll need to make sure that our file type is recognized by NetBeans IDE though, which simply means working through a wizard that generates the necessary code. So, we forget the file chooser, because we're going to leverage the Favorites window. Secondly, we have a JPanel. To integrate it with the NetBeans IDE (i.e., NetBeans Platform), we'll need to create a TopComponent instead (click here for details on TopComponents). This is simply an embeddable visual component for display in NetBeans Platform applications, such as the IDE. There's a wizard for that. Once we have the TopComponent, we'll simply transfer our code from the Swing application's JPanel to the TopComponent.

So, let's port our Swing application to a module that we will install in NetBeans IDE:

  1. Creat a module project called MoviePlayerModule.

  2. Use the New File Type wizard to generate code that will let the IDE recognize files with the extension used by your movies (e.g., AVI, or MOV, or FOB, or all three). Choose an icon in the wizard, so that you'll be able to see that the IDE distinguishes your file type from all others.

  3. Use the New Window Component wizard to generate a TopComponent.

  4. Now install your module. In the Favorites window (Ctrl-3), notice that you can right-click and browse to a folder of your choice. If you browse to a folder containing your movies, with the file type you specified in the New File Type wizard, you should see that the movie files have the icon that you specified in the wizard:

    You see? There's no need to create a file chooser in our module, because we already have one in NetBeans IDE (it is part of the NetBeans Platform so is available to any application built on top of it).

  5. Next, we want our files to open inside our TopComponent. If you look in your file type's DataObject code, you'll see this line in the constructor:

    cookies.add((Node.Cookie) DataEditorSupport.create(this, getPrimaryEntry(), cookies));

    As a result of this line, the file will try to open in a very simple text editor (provided by DataEditorSupport). This is not good news, because we have binary data. Let's tell the constructor that we will create a new class that will handle the opening of our files. So replace the above line with this one:

    getCookieSet().add(new MyOpenSupport(getPrimaryEntry()));

    You'll get a red underline because you haven't created that MyOpenSupport yet. Create it now and implement it as follows:

    public class MyOpenSupport extends OpenSupport implements OpenCookie, CloseCookie{
        
        public MyOpenSupport(MyDataObject.Entry entry) {
            super(entry);
        }
        
        protected CloneableTopComponent createCloneableTopComponent() {
            MyDataObject dobj = (MyDataObject)entry.getDataObject();
            MyTopComponent tc = new MyTopComponent(dobj);
            tc.setDisplayName(dobj.getName());
            return tc;
        }
        
    }

  6. Now you need to make your TopComponent public, change the constructor to public, receive the data object in the constructor, and change the TopComponent's extension class to CloneableTopComponent. (This will let us open multiple movies, while simultaneously meeting the expectation of OpenSupport.createCloneableTopComponent().)

    Now there are several methods that you need to comment out for now: getDefault(), findInstance(), as well as the writeReplace() and ResolvableHelper at the end. You can just delete the content of the action's performAction(), because we don't need the entire menu item anyway.

  7. Install the module again. Now go to the Favorites window and notice that when you right-click a movie file and choose Open... a new window opens, with the name of the file placed in the tab. Hurray! We're now almost there. All we now need to do is transfer the code from our Swing application to the TopComponent.

  8. Take all the code we added to the MediaPanel previously and stick it into the TopComponent's constructor, after the last line that is there already. (That code could be more complex, but let's leave that for another time. This is not a JMF tutorial, after all. Go here for JMF documentation.)

    However, add this within the try/catch block, to replace some of the work done by the file chooser in the Swing application:

    URL mediaURL = FileUtil.toFile(dobj.getPrimaryFile()).toURI().toURL();

    Again, if you have the JMF JARs and related libraries installed on your system, you don't need to provide them with your module. If you want to provide them with your module, create a module suite project, add a library wrapper module project, and declare a dependency on the library wrapper, using the module's Libraries panel.

    And that's it! Now install the module again. Open the movie file and notice that it now displays within the TopComponent. You probably want it to display in a JPanel instead. You can tweak the code in the TopComponent's constructor accordingly. In addition, you probably want to make sure that the player closes when the TopComponent closes (Player.close() in TopComponent.componentClosed()).

And now you've ported your Swing application to a NetBeans module and installed it in the IDE. Hurray!

An advantage of having your own module that runs movies is that you can extend it. (Unlike all other movie players out there. Is there even one movie player in the world that allows you to add completely new functionality? I'm willing to bet that there isn't.) For example, let's say you want to see movie reviews while watching your movie. You can create a completely new module that provides a "Read Review" action, which opens the related movie page from the Internet Movie Database. Here the related review opens in the Swing browser, but it could also be an external brower or Rich Unger's JDIC browser:

Of course, none of this functionality need be limited to NetBeans IDE. You can take the Favorites window, "Read Review" functionality, and movie player...

...and then you can reuse these features in any other application based on the NetBeans Platform, such as the JFugue Music Player, for example. Or... you could make an entire application dedicated to playing movies. That's what the final part of this series will discuss.

Postscript. If you're considering working with JMF, I highly recommend that you read JMF 2.1.1 - Known Issues. Better to know beforehand where you're likely to get burnt. For example, this is issue 18:

  • 18. JMF may run out of memory in the following situations:
    • The close method is not being called on Players or Processors when they are no longer being used. Without calling close, the Players or Processors will not release the memory and other resources (e.g. live threads).
    • There are still some external references to an unused Player or Processor such that garbage-collection is not taking place. References may come in many different ways. One of the less obvious ones is the player's visual and control component not being removed from their container components.
    • Some movies might require more memory to play than is available from the Java VM. In this case, you'll need to allocate more memory for JVM to run. For example, by issuing the command: "java -mx32m".
    • JVM might temporarily run out of memory after playing a few movies in succession. This is usually temporary and the VM can recover after garbage-collection. If you reload the movie a second time, sometimes it will work.

Comments:

Hello.
Great serie. I am having the same problem as you, that is having the dll being recognized when in a library wrapper module.
I did not find the details on how you made that possible. Can you please tell me more on that?
Thank you !

Posted by frederic barachant on October 12, 2007 at 01:03 AM PDT #

Hi Frederic. This should help you, and if not, write to dev@openide.netbeans.org:
http://wiki.netbeans.org/wiki/view/NativeLibrariesInNetbeans

Posted by Geertjan on October 12, 2007 at 01:11 AM PDT #

Hello.
That's exactly what i did, unfortunatly.
Based on your 18 january 2007 blog, i thought you indicated that this was not working.
I must have made a mistake... somewhere...

Thank you for your help.

Posted by frederic barachant on October 12, 2007 at 05:04 PM PDT #

it's really good...

and iam requesting you to please give me(to my mail ID) the java code for streaming a video file and playing the video streames using JMF....

Posted by sivaram on April 15, 2008 at 06:39 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today