How to play next video without using playlist? - winforms

I'm using Windows Form Applications in visual c++ 2010 to create a GUI that has embedded a Windows Media Player. I'm trying to creat a button that when is pressed it plays two consecutive video files. When I use the code bellow, only the last avi file plays. Do you know why the first avi doensn't play?
private: System::Void BtnB_Click(System::Object^ sender, System::EventArgs^ e) {
axWindowsMediaPlayer1->Ctlcontrols->play();
axWindowsMediaPlayer1->URL="DG.avi";
axWindowsMediaPlayer1->Ctlcontrols->play();
axWindowsMediaPlayer1->URL="IG.avi";
}
Thank you.

Related

Changing MediaElement source without Flicker

I have a simple video player that plays a series of videos using the WPF MediaElement. The videos together form one continuous film that move around a still image. At the end of each video the movement freezes on the final frame of the currently playing video. When I press a button the next video plays, which continues the movement around the still image. It's an application I'm going to use to give a speech. Effectively I've got a series of videos for which the last frame of each video is the same as the first frame of the next video.
I'm using a WPF MediaElement and changing the Source property when the user clicks on the mouse.
The problem that I have is that, when I change the Source property, the MediaElement becomes transparent while the next video is loaded. This means there is a flicker between videos. Is there any way of preventing this flicker? What other strategies could I use?
Here's some code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.x_MediaElement.MouseLeftButtonDown += x_MediaElement_MouseLeftButtonDown;
this.MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MoveNext();
}
private void MoveNext()
{
_sourceIndex++;
if (_sourceIndex >= _sources.Length)
_sourceIndex = 0;
Debug.WriteLine(string.Format("Playing {0}", _sources[_sourceIndex]));
this.x_MediaElement.Source = new Uri(_sources[_sourceIndex]);
this.x_MediaElement.Play();
}
private int _sourceIndex = -1;
private string[] _sources = new string[] {
//SOURCE GO HERE
};
void x_MediaElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MoveNext();
e.Handled = true;
}
}
I am gonna be honest with you. MediaElement has more bugs than you can count with fingers. Starting from that the mediaElement blows up after playing 20 videos(no more MediaEnded event, it will crash or something like that). And ofcourse the performance. Its not synchronized with vertical sync. So the video might actually seem laggy.
I advise you to look into DirectShow technology(essentially what WPF is based on, but you can switch renderer which will avoid lag). COnsidering that you will not be developing any professional application, I guess MediaElement will be fine.
However, MediaElement is the simplest option, and if it works for you, then keep working with it. As for your problem, I think there are few possible solutions:
Have two MediaElements and switch between them. If one video ends, start another vid in another MediaElement, as long as you play first frame on second mediaElement, hide the first mediaElement, and vice versa. You can poll for position, and maybe MediaStarted event. This way the flicker will be almost impossible to notice.
If you want fluent video playing without ANY flicker at all, there is GMFPlay. You can check it out. Though it's not MediaElement. But it can play videos simultaneously without any flicker.
Take screenshot of the last frame(you can take screenshots with WPF) and show it as Image while MediaElement is secretly loading.

How can i check that media element is play file or not?

i want to play an audio or video file, and i made this but i do not know how i can check whether media element is playing file or not?
Like using same button for Pause and Play how i can know that media is also playing file or not?
i use below code to play the file
mediaElement1.LoadedBehavior = MediaState.Manual;
mediaElement1.Source = new Uri("C:/test.wma", UriKind.RelativeOrAbsolute);
mediaElement1.Play();
And one more thing i know how to play file in media element by code. I want to to design media element UI. how i can design this for both video and audio files? what properties should enable and what should be disable.
Last I checked you can't unless you are using Silverlight:
http://msdn.microsoft.com/en-us/library/cc189079(v=vs.95).aspx
I have an application using .Net 4 and as far I can remember you cannot verify if it is playing, stopped, paused, etc.
This is what you can do with .Net 4:
http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(v=vs.100).aspx
Compared with Silverlight:
http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(v=vs.95).aspx

How can I play an audio file in WPF mediaElement without waiting for it to load the file completely ?

I have several large WAV files (about 5 - 10 minutes in play time) that I want to play via WPF MediaElement. But when I set the source to one of these files and call the Play method, MediaElement seems to wait untill the file has loaded completely before begining to play it. Any one know of a way to get it to play while the rest of the file is loaded. Or suggest another way to play these WAV files back, not using MediaElement?
Add mediaElement controll to your window then add following code to play the audio file
mediaElement1.LoadedBehavior = MediaState.Manual;
mediaElement1.Source = new Uri("C://test.wma", UriKind.RelativeOrAbsolute);
mediaElement1.Play();
this code works for me.

Why does WPF MediaElement not work on secondary monitor?

My application uses the WPF MediaElement to play video (MOV files). This works well when playing on the Primary monitor but freezes when the window is moved to the secondary monitor.
I have tried the following without success:
Starting the application on the secondary monitor
Swapping the primary & secondary monitors (problem transfers to the new secondary monitor)
When the application window spans both monitors it works correctly but as soon as it is entirely within the secondary monitor the video freezes. Once in this state, moving the application back to the primary monitor doesn't help (and loading a new video doesn't help either).
The monitors are arranged so that the co-ordinates are always positive (both monitors are 1920x1080 and the secondary monitor origin is 1920,0).
Has anyone else seen this problem and/or found a fix?
EDIT
Does anyone use the WPF MediaElement with multiple monitors???
This is still a known issue in .NET Framework 4.0, which MS described as "The issue occurs when a synchronization between WPF and the underlying WMP control have to resynchronize when the display changes occur." It happens to H.264 codec video files.
Here are 3 workarounds.
1 . Use software rendering for the window containing the MediaElement control
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
var hwndTarget = hwndSource.CompositionTarget;
if (hwndTarget != null) hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
}
However this is not utilizing the GPU and graphics memory and could slow down the video playback.
2. Overlap at least 1 pixel onto the primary display
For example, suppose the primary screen in on the left, and the MediaElement fills the entire window. In the window's constructor, suppose Rect bounds represents the secondary monitor boundary, use
this.Left = bounds.Left - 1;
this.Width = bounds.Width;
this.Top = bounds.Top;
this.Height = bounds.Height;
so the MediaElement has 1 pixel wide overlapped on the primary monitor, and then it's able to play H.264 video files normally.
3. Use another MP4 codec other than MS's Media Foundation codec
Download a tool "Win7DSFilterTweaker" to disable Media Foundation "MP4" playback.
Install another MP4 codec, ffshow, for example.
Check if events: MediaOpened, MediaEnded and MediaFailed are still being raised.
I assume not as this is a known issue that this control "ignores" the second monitor.

Adding a minimum display time for Silverlight splash screen

When hosting a silverlight application on a webpage it is possible to use the splashscreensource parameter to specify a simple Silverlight 1.0 (xaml+javascript) control to be displayed while the real xap file is downloaded, and which can receive notification of the downloads progress through onSourceDownloadProgressChanged. If the xap file is in cache, the splash screen is not shown (and if the download only takes 1 second, the splash screen will only be shown for 1 second).
I know this is not best practice in general, but I am looking for a way to specify a minimum display time for the splash screen - even if the xap cached or the download is fast, the splash screen would remain up for at least, let's say, 5 seconds (for example to show a required legal disclaimer, corporate identity mark or other bug).
I do want to do it in the splash screen exclusively (rather then in the main xap) as I want it to be clean and uninterupted (for example a sound bug) and shown to the user as soon as they open the page, rather then after the download (which could take anywhere from 1 to 20+ seconds).
I'd prefer not to accomplish this with preloading - replacing the splash screen with a full Silverlight xap application (with it's own loading screen), which then programmably loads and displays the full xap after a minimum wait time.
Its a little known fact that the splash screen remains in place beyond the time that XAP takes to load. It doesn't get replaced until the application RootVisual loads. Hence if you don't assign the RootVisual in the application Startup event the splash screen displays forever.
Hence you can delay the display of the splash for a few seconds using code like this:-
private void Application_Startup(object sender, StartupEventArgs e)
{
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(10);
EventHandler eh = null;
eh = (s, args) =>
{
timer.Stop();
this.RootVisual = new Test();
timer.Tick -= eh;
};
timer.Tick += eh;
timer.Start();
}
This can be simplified with the Reactive framework:-
private void Application_Startup(object sender, StartupEventArgs e)
{
Observable.Timer(TimeSpan.FromSeconds(10), Scheduler.Dispatcher)
.Subscribe((l) =>
{
this.RootVisual = new Test();
});
}
However the Reactive framework adds at least 66KB to the size of your Xap so only use it you are already using the Reactive stuff for other things.
Note that if you were only interested in extending the display time of the splash screen during development then it is very simple to add a Fiddler rule which delays the response off the Xap file.
This is an example of a rule that would have this effect. See Pedro Forte's post for details on how to apply the rule - it is really very easy!
if (oSession.uriContains("Midwinter.ReasonableBasis.Client.xap")){
oSession["ui-color"]="orange";
oSession["ui-bold"]="true";
//Delay received data by X ms per KB downloaded.
oSession["response-trickle-delay"] = "10";
}

Resources