JamesChambers-rvng

Hello all,


We've been working away at getting HostVisual and VisualTarget working, and I'm hoping someone out there can give us a little more insight.

At this point we are inheriting from FrameworkElement and using DrawingVisual and HostVisual to host a MediaPlayer. The next step, rigging up VisualTarget and getting a secondary thread on the go, is where we're at a loss.

Below is the code we currently have; I've included the important bits. If you want to test this, just comment out the event handlers and come up with a WMV file.

Code Snippet

public class HostedMediaPlayer : FrameworkElement
{
public event EventHandler<MediaEventData> ErrorHappened;

DrawingVisual _dv = null;
HostVisual _hv = null;

public HostedMediaPlayer()
{
_dv = new DrawingVisual();
_hv = new HostVisual();
MediaPlayer mp = new MediaPlayer();

// rig up the Media Player
mp.MediaFailed += new EventHandler<ExceptionEventArgs>(mp_MediaFailed);
mp.Open(new Uri(@"C:\video\test.wmv"));
mp.MediaEnded += new EventHandler(mp_MediaEnded);

// tie the video to the DrawingVisual's context
using (DrawingContext dc = _dv.RenderOpen())
{
dc.DrawVideo(mp, new Rect(0, 0, 320, 240));
}

// configure the HostVisual to host the DrawingVisual and add it
// to the FrameworkElement's visual/logical children
_hv.Children.Add(_dv);
AddVisualChild(_hv);
AddLogicalChild(_hv);

// start the video
mp.Play();

}

//<snipped MediaPlayer event handlers />

protected override int VisualChildrenCount
{
get
{
return 1;
}
}
protected override Visual GetVisualChild(int index)
{
if (index != 0)
throw new ArgumentOutOfRangeException("index");

return _hv;
}

}

This code works just fine. In fact, if you create an instance of the above class and put it on a WPF form the video plays almost instantly.

We know that VisualTarget accepts a HostVisual as a param in the constructor, but this doesn't really clarify the roles each play to each other.

My questions would be as follows:

1) how do you involve VisualTarget from here

2) where does the secondary thread come from

Any help is appreciated.

Cheers,

James



Re: Windows Presentation Foundation (WPF) HostVisual and VisualTarget

LSDev_KF

This might be a stupid question, but why don't you just use a MediaElement control That way, you get built-in support for Media Player. There's a good example in the SDK samples under WPFSamples\GraphicsMM_Media\MediaGallery





Re: Windows Presentation Foundation (WPF) HostVisual and VisualTarget

JamesChambers-rvng

No stupid questions here.

We have been trying to deal with poor UI response while a video is loading, and are trying to get the load to occur on a seperate thread. When you call Open() on a MediaElement the player begins playing the file immediately...unless you set LoadedBehaviour to Manual, in which case the file doesn't load until you call Play().

Regardless, the feedback I've gotten from a couple of Microsoft employees (through blogs, this forum, via email) has been to use HostVisual and VisualTarget as these objects take care of the cross-thread requirements such operations, allowing me to load the video on a seperate thread and still have it display on the UI thread. Unfortunately, searches for such examples have proven fruitless.

To answer your question, it really shouldn't matter if, at this point, I use MediaElement or MediaPlayer; the control selected is just part of the excercise.

Cheers,

James





Re: Windows Presentation Foundation (WPF) HostVisual and VisualTarget

LSDev_KF

Have you tried creating a MediaElement in Manual mode and when the audio source is loaded you can call mediaPlayer.Pause(); to load the file in a paused state



Re: Windows Presentation Foundation (WPF) HostVisual and VisualTarget

JamesChambers-rvng

Yes, in our tests we tried doing this.

We were using two MediaElements and trying to play them back-to-back according to a playlist of WMV files.

I had handlers setup for MediaLoaded and MediaEnded. When MediaLoaded on the second video fired, I'd pause the video and wait for MediaEnded on the first. When I started playing the second, I would try to load the first with the next video in the playlist. Lather, rinse, repeat.

When we have one video playing, however, and try to get the second one loading the UI blocks while the player loads/caches/whatever it does to the video; thus, our search for a background thread approach.

Cheers.