對不起,如果我不像我一樣清楚。實際上,MediaElement
具有Position
屬性,但它不是DependancyProperty
,並且不是可綁定的。也無法直接通過事件檢索更新的位置。所以我很久以前使用的方式是在StoryBoard中使用MediaTimeLine。你應該看看這個帖子,來自Microsoft的How to: Control a MediaElement by Using a Storyboard。 我用這種方式使用MediaElement來查找視頻文件。另一種方式是使用名爲WPFMediaKit的第三方庫,這非常有用。你可以找到它 WPF MediaKit - For webcam, DVD and custom video support in WPF
第一實例:使用WPFMediaKit(沒有實際的方式來播放MP4文件...)
在WPF MediaKit的MediaUriElement
允許你綁定其MediaPosition
,因爲它是一個DependancyProperty
。該MediaUriElement
是圍繞淨MediaElement
一個包裝物,在functionnalities差。所以,參考我的第一個答案,我寫了一個非常簡單的POCO。你可以寫這樣的事情:
MainWindow.xaml
<Window x:Class="Media.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:media="clr-namespace:WPFMediaKit.DirectShow.Controls;assembly=WPFMediaKit"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="SwitchToSecondPlayerStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="firstPlayer">
<DiscreteObjectKeyFrame KeyTime="0:0:0.7" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="secondPlayer">
<DiscreteObjectKeyFrame KeyTime="0:0:0.7" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="switchButton">
<BeginStoryboard Storyboard="{StaticResource SwitchToSecondPlayerStoryboard}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<media:MediaUriElement x:Name="firstPlayer" Source="firstFile.wmv" LoadedBehavior="Play"/>
<media:MediaUriElement x:Name="secondPlayer" Source="secondFile.wmv" MediaPosition="{Binding Path=MediaPosition, ElementName=firstPlayer}" Visibility="Collapsed" Volume="0"/>
<Button Grid.Row="1" x:Name="switchButton" Content="SWITCH NEXT FILE" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnSwitchButtonClick"/>
</Grid>
這裏是MainWindow.xaml。cs
namespace Media
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnSwitchButtonClick(object sender, RoutedEventArgs e)
{
//Do whatever you want with the players.
}
}
}
此程序的工作原理並沒有「空白屏幕」效果。您只需改進Storyboard
轉換(帶有FadeIn效果的示例),但這是原則。 你也會注意到第二個的MediaPosition
綁定到第一個的MediaPosition
。 這意味着總是檢查MediaPosition
是否低於該文件的Duration
以避免錯誤,但這只是代碼的東西。
請注意,我簡化了我的代碼,避免使用MVVM和其他體系結構,以保持更清晰。
第二溶液:使用MediaElement
MainWindow.xaml解決方法
<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 Background="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>
MainWindow.xaml.cs
using System;
using System.Timers;
using System.Windows;
namespace Media
{
/// <summary>
/// Interaction logic for pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public TimeSpan Position { get; set; }
Timer _updateTimer;
public MainWindow()
{
InitializeComponent();
//Timer interval fixed to 1 second to read the actual position of the first media element
this._updateTimer = new Timer(1000);
this._updateTimer.Elapsed += this.UpdateTimerElapsed;
}
//The callback of your update timer
private void UpdateTimerElapsed(object sender, ElapsedEventArgs e)
{
//I use the dispatcher because you call the Position from another thread so it has to be synchronized
Dispatcher.Invoke(new Action(() => this.Position = firstMediaElement.Position));
}
//When stopping the first, you start the second and set its Position
private void OnLaunchNextButtonClick(object sender, RoutedEventArgs e)
{
this.firstMediaElement.Stop();
this.secondMediaElement.Volume = 10;
this.secondMediaElement.Play();
this.secondMediaElement.Position = this.Position;
}
//When you start the first, you have to start the update timer
private void OnLaunchFirstButtonClick(object sender, RoutedEventArgs e)
{
this.firstMediaElement.Play();
this._updateTimer.Start();
}
}
}
這些都是隻能提供簡單的解決方案。有不同的方法來做到這一點,特別是使用MediaTimeline
,但實現並不像看起來那麼容易,關於你面臨的問題。第二個例子,第一個例子是完全編譯和運行,並且以我想要的目標爲目標。
希望這會有所幫助。隨時給我您的反饋。
謝謝你的所有詳細解答。可悲的是,我不太瞭解StoryBoard和MediaKit如何幫助我實現我的要求。 –
我剛剛編輯我的帖子來編寫一個WPFMediaKit的使用示例。它像你想要的那樣工作。讓我知情。 – jhontarrede
我真的很抱歉,我很困擾你,但我無法讓MediaUriElement工作。我做了一個新的項目,我添加了對WPFMediaKit.dll的引用,並且還做了xmlns:media。我的程序只包含這一行: 。沒有編譯錯誤,但是當我運行它時,它只是不起任何作用。我錯過了什麼嗎?從來沒有與DLL的工作之前..非常感謝。 –