3 Replies Last post: May 6, 2008 8:55 PM by Serge Piletsky  
Tedd Alevo   3 posts since
May 3, 2008
Currently Being Moderated

May 3, 2008 3:31 AM

Windows Media Player in a Console

Hi,

 

I'm currently evaluating ComfyJ and I have to admit this software looks very promising. However, I have some problems getting a simple program to work which is supposed to play a media file using WMP11 without having a GUI.

 

 

Program:

public static void main(String[] args) throws MalformedURLException {

 

ComFunctions.coInitialize();

          

String filename = "F:
WM9SDK
WMPSDK9
samples
media
jeanne.wma";

          

CLSID id = CLSID.createFromProgID("WMPlayer.OCX");

System.out.println("CLSID= " + id);

IWMPPlayer4 player = null;

          

try {

     player = new IWMPPlayer4Impl(id, ClsCtx.INPROC_SERVER);

} catch (ComException e) {

     e.printStackTrace();

}

     if (player != null) {

          BStr theVersion = player.getVersionInfo();

          System.out.println("IWMPPlayer4.getVersionInfo(): " + theVersion);

          System.out.println("Status= " + player.getStatus());

          System.out.println("PlayState= " + player.getPlayState());

          System.out.println("ErrorCount= " + player.getError().getErrorCount());

          

          player.setURL(new BStr(filename));

          System.out.println("Status= " + player.getStatus());

          System.out.println("PlayState= " + player.getPlayState());

 

          IWMPControls theControls = player.getControls();

          theControls.play();

               

          IWMPMedia theCurrentItem = theControls.getCurrentItem();

          System.out.println("CurrentItem name= " + theCurrentItem.getName());

          System.out.println("CurrentItem source url= " + theCurrentItem.getSourceURL());

               

          for (int i = 0; i < 50; i++) {

               System.out.println("Status= " + player.getStatus());

               System.out.println("PlayState= " + player.getPlayState());

               System.out.println("ErrorCount= " + player.getError().getErrorCount());

 

          try {

               Thread.sleep(1000);

          } catch (InterruptedException e) {

          }

     }

}

}

 

Output:

CLSID= {6BF52A52-394A-11D3-B153-00C04F79FAA6}

IWMPPlayer4.getVersionInfo(): 11.0.5721.5230

Status=

PlayState= 0

ErrorCount= 0

Status= Medium wird geöffnet...

PlayState= 9 <- Transitioning

CurrentItem name= jeanne

CurrentItem source url= F:\WM9SDK\WMPSDK9\samples\media\jeanne.wma

Status= Medium wird geöffnet...

PlayState= 9

ErrorCount= 0

Status= Medium wird geöffnet...

PlayState= 9

ErrorCount= 0

Status= Medium wird geöffnet...

 

 

Of course, this works with the sample code you provided, however this sample is with gui.

 

The code is quite straight forward, as I think. There are no COM exceptions and if I try to access the MediaCollection this works as well (corrent number of media items returned). As I'm new to COM, I might be missing something fundamental (section 4.5 of programing guide was a little bit too much magic for me...) and I'd be quite happy if you could help me out.

 

Cheers,

Tedd

Serge Piletsky TeamDev Ltd. 670 posts since
Apr 24, 2006
Currently Being Moderated
3. May 6, 2008 8:55 PM in response to: Tedd Alevo
Re: Windows Media Player in a Console

Hi Tedd,

 

Sorry for the delay in getting back to you. And thanks for posting the updates on this issue.

 

When you work with Windows Media Player (WMP) ActiveX component (ProgID is WMPlayer.OCX) we should bear in mind the following:

1) this component does not support multi threading properly: even though it's possible to create this component in one thread and call some property getters from another thread, it's not possible, for example, to create a player in one thread and call its play() method from another thread - it simply will not start the playback. Therefore only one thread should be used;

 

2) this component requires message loop in order to work properly. By "message loop" here I mean a thread which processes Windows events in standard GetMessage/TranslateMessage manner. And since this is a visual ActiveX component such message processing is required even though a component is invisible. For this purpose you can use OleMessageLoop thread which actually provides such ability;

 

The following example demonstrates how to overcome both these restrictions:

final String filename = "F:\\WM9SDK\\WMPSDK9\\samples\\media\\jeanne.wma";
OleMessageLoop.invokeAndWait(new Runnable() {
    public void run() {
        CLSID id = CLSID.createFromProgID("WMPlayer.OCX");
        System.out.println("CLSID= " + id);
        IWMPPlayer4 player = new IWMPPlayer4Impl(id, ClsCtx.INPROC_SERVER);
        player.setURL(new BStr(filename));
 
        IWMPControls theControls = player.getControls();
        theControls.play();
    }
});
System.in.read();

 

However, if you need to work with "player" object in another Java thread then the following example could be useful:

public class HeadlessMediaPlayer {
    private IWMPPlayer4 player;
    private OleMessageLoop oleMessageLoop;
    private final CLSID id = CLSID.createFromProgID("WMPlayer.OCX");
 
    public HeadlessMediaPlayer() {
        oleMessageLoop = new OleMessageLoop();
        oleMessageLoop.doStart();
        try {
            oleMessageLoop.doInvokeAndWait(new Runnable() {
                public void run() {
                    // create media player in the message loop thread
                    player = new IWMPPlayer4Impl(id, ClsCtx.INPROC_SERVER);
                }
            });
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        // "bind" player object into the message loop
        player = (IWMPPlayer4) oleMessageLoop.bindObject(player);
    }
 
    public void play(String file) {
        player.setURL(new BStr(file));
        player.getControls().play();
    }
 
    public void release() {
        player.setAutoDelete(false);
        player.release();
        oleMessageLoop.doStop();
    }
 
    public static void main(String[] args) throws Exception {
        final HeadlessMediaPlayer headlessMediaPlayer = new HeadlessMediaPlayer();
        Thread anotherThread = new Thread(new Runnable() {
            public void run() {
                // now we can call play method from another thread
                headlessMediaPlayer.play("D:\\Media\\Audio\\O-WAB-03_V_128_48_2.wma");
            }
        });
        anotherThread.start();
        System.in.read();
        headlessMediaPlayer.release();
    }
}

 

Please let me know if you have another questions.

 

-Serge

More Like This

  • Retrieving data ...