I am working on a video project. In that project there will be a video playing for the user, and if the user clicks a button- that video is changed to the next one. Point is, the next video will play from the point the previous one stopped in (So if the user presses the NEXT button at 00:00:30 the next video will play from that point).
The problem I am facing is that there are always a few moments of black screen until the next video will play, and I want the change to be smooth without the user watching a black screen for a second or two. In one of my tries I have managed to get rid of the black screen but then a new problem appears - the timing of the switch is not 100% perfect.
So far, I've tried to solve it with different approaches :
Approach one: (For some reason still shows a black screen while having time delay)
<Window x:Class="Media.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="ShowSecond">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="firstMediaElement">
<DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="secondMediaElement">
<DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="btnlaunchNext">
<BeginStoryboard Storyboard="{StaticResource ShowSecond}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<StackPanel removed="Black">
<MediaElement Name="firstMediaElement" LoadedBehavior="Manual" Source="firstFile.mp4" Width="260" Height="150" Stretch="Fill" />
<MediaElement Name="secondMediaElement" Volume="0" LoadedBehavior="Manual" Source="secondFile.mp4" Visibility="Collapsed" Width="260" Height="150" Stretch="Fill" />
<!-- Buttons to launch videos. -->
<Button x:Name="btnlaunch" Content="PLAY FIRST" Click="OnLaunchFirstButtonClick"/>
<Button x:Name="btnlaunchNext" Content="PLAY NEXT" Click="OnLaunchNextButtonClick"/>
</StackPanel>
</Grid>
</Window>
and the .cs :
using System;
using System.Timers;
using System.Windows;
namespace Media
{
public partial class MainWindow : Window
{
public TimeSpan Position { get; set; }
Timer _updateTimer;
public MainWindow()
{
InitializeComponent();
this._updateTimer = new Timer(1000);
this._updateTimer.Elapsed += this.UpdateTimerElapsed;
}
private void UpdateTimerElapsed(object sender, ElapsedEventArgs e)
{
Dispatcher.Invoke(new Action(() => this.Position = firstMediaElement.Position));
}
private void OnLaunchNextButtonClick(object sender, RoutedEventArgs e)
{
this.firstMediaElement.Stop();
this.secondMediaElement.Volume = 10;
this.secondMediaElement.Play();
this.secondMediaElement.Position = this.Position;
}
private void OnLaunchFirstButtonClick(object sender, RoutedEventArgs e)
{
this.firstMediaElement.Play();
this._updateTimer.Start();
}
}
The second approach(Perfect timing + Black screen):
TimeSpan Time = mediaElement1.Position;
mediaElement1.Source = new Uri(NEW PATH);
mediaElement1.Position = Time;
mediaElement1.Play();
Third approach(Using two mediaElements and a timer to smooth the change up[There's no black screen!], still the timing is not perfect - obviously.. and it is a hard time for the machine to play 2 videos at the same time):
mediaElement2.Source = new Uri(VideoArr[Index].FullName);
mediaElement2.Position = mediaElement1.Position + new TimeSpan(0, 0, 1); ;
mediaElement2.Play();
mediaElement2.Volume = 0;
mediaElement2.Visibility = Visibility.Visible;
Stopwatch st = new Stopwatch();
st.Start();
while (st.ElapsedMilliseconds < 1000) { }
mediaElement1.Visibility = Visibility.Collapsed;
mediaElement2.Volume = 0.5;
mediaElement1.Source = null;
mediaElement1.Position = new TimeSpan();
Thanks in advance for any light on that matter, couldn't find a way to succeed in both preventing the black screen while keeping a perfect timing while transfering the videos.
EDIT : Using MediaKit can not help because it does not support .MP4's.