我有一个使用MediaElement
的WPF应用程序。
我想循环播放视频的某个部分。我有一个StartTime
和EndTime
变量用于循环目的。我尝试DispatcherTimer
用于循环目的,但它对于小于1秒的循环来说太慢了。所以我尝试了简单的while循环,如下所示。
while (true)
{
if(!buttonPressed)
{
while (mePlayer.Position < loop.EndTime) ; //go till end of loop
mePlayer.Position = loop.StartTime; //after reaching end of loop start again
}
}
使用上面的代码,甚至0.5秒的视频循环正常但是 上述方法的问题是,一旦它进入无限循环,它就无法检测按钮按下,因此我无法停止循环。所以我的问题是如何在while循环中检测按钮按下,以便我可以停止循环视频并继续执行其他任务?
答案 0 :(得分:1)
我很惊讶您无法获得有关视频播放进度的任何信息。但是你可以通过组合Task
和Dispatcher
(因为跨线程)来解决这个问题,而不会阻止用户界面,如下所示。
<强> MainWindow.xaml.cs 强>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private CancellationTokenSource _tokenSource;
private double _start;
private double _stop;
public MainWindow()
{
InitializeComponent();
DataContext = this;
media.LoadedBehavior = MediaState.Manual;
Start = 0;
media.MediaOpened += (sender, args) =>
{
Stop = (int)media.NaturalDuration.TimeSpan.TotalSeconds;
SetEndPosition();
};
media.Source = new Uri("video.wmv", UriKind.Relative);
media.Play();
}
private async void SetEndPosition()
{
_tokenSource?.Cancel();
_tokenSource = new CancellationTokenSource();
var token = _tokenSource.Token;
await Task.Run(() =>
{
if (token.IsCancellationRequested)
return;
while (!token.IsCancellationRequested)
{
Dispatcher.Invoke(() =>
{
double position = media.Position.TotalSeconds;
if (position >= Stop)
SetStartPosition();
});
Thread.Sleep(100);
}
}, token);
}
private void SetStartPosition()
{
media.Position = TimeSpan.FromSeconds(Start);
}
public double Start
{
get { return _start; }
set { _start = value; OnPropertyChanged(); SetStartPosition(); }
}
public double Stop
{
get { return _stop; }
set { _stop = value; OnPropertyChanged(); }
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<强> MainWindow.xaml 强>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow"
Height="422"
Width="450">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="340" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<MediaElement Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,10" x:Name="media" />
<TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Start}"></TextBox>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Stop}"></TextBox>
</Grid>