WPF Mediaelement LoadedBehavior 不能正常工作?
WPF Mediaelement LoadedBehavior does't work correctly?
我正在用 VB.NET 代码在 WPF 中创建一个简单的应用程序。此代码完美运行。选择文件后,函数returns根据媒体类型正确编号,当媒体是音频文件时出现音符图像,否则消失。媒体自动播放。但是我不需要自动播放媒体,当我将 LoadedBehavior 设置为手动(而不是默认播放)时,奇怪的事情发生了。 MediaOpened 事件会不时触发,函数 returns 有时为零,有时是正确的数字,有时是错误的数字。我在谷歌上搜索了将近三天,但一无所获。我想让 MediaElement.Play 和 MediaElement.Pause 显示 video/image 的第一帧,但如果没有将 LoadedBehavior 设置为手动,这是不可能的。我想以某种方式避免 LoadedBehavior。有人可以给我提示吗?非常感谢您。
Private Sub btnFile_Click(sender As Object, e As RoutedEventArgs) Handles btnFile.Click
Try
Me.MediaElementSetting.LoadedBehavior = MediaState.Manual
Me.MediaElementSetting.UnloadedBehavior = MediaState.Close
Me.MediaElementSetting.Stop()
Me.MediaElementSetting.Close()
Me.PvwTimer.Stop()
Catch ex As Exception
'The exception occurs when LoadedBehavior is not set to manual, that's why it's unused
'MsgBox(ex.ToString)
End Try
Dim ArrayIndes as Integer = 1
OpenFileDialog(ArrayIndex)
End Sub
Sub OpenFileDialog(ByVal ArrayIndex As Integer)
Dim Dlg1 As New System.Windows.Forms.OpenFileDialog
Dlg1.ShowDialog()
If Dlg1.FileName <> "" Then
strFile = Dlg1.FileName
Me.MediaElementSetting.Source = New Uri(strFile, UriKind.RelativeOrAbsolute)
End If
End Sub
Private Sub MediaElementSetting_MediaOpened(sender As Object, e As RoutedEventArgs) Handles MediaElementSetting.MediaOpened
Dim t As Integer = AV()
End Sub
Function AV() As Integer
'Check, if the media has timespan (if it is image, audio, video w sound, video w/o sound - image has video without timespan)
If Me.MediaElementSetting.NaturalDuration.HasTimeSpan = True Then
If Me.MediaElementSetting.HasAudio = True Then
If Me.MediaElementSetting.HasVideo = True Then
'Media is a video with sound
MediaInfo = 4
Else
'Media is an audio
MediaInfo = 2
End If
Else
If Me.MediaElementSetting.HasVideo = True Then
'Media is a video without sound
MediaInfo = 3
End If
End If
Else
If Me.MediaElementSetting.HasVideo = True Then
'Media is an image
MediaInfo = 1
End If
End If
If MediaInfo = 2 Then
'Note is an image in a window. When the media is an audio it covers the mediaelement in a window
Note.Visibility = Visibility.Visible
Else
Note.Visibility = Visibility.Hidden
End If
Return MediaInfo
End Function
我不是 VB.NET 人,但这是 C# 中的一个工作示例。
这是 XAML。我有一个 MediaElement
,一个 Border
作为笔记图像的 stand-in,还有一个按钮。
MainWindow.xaml
<Window x:Class="SO.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SO"
Title="MainWindow"
Width="800"
Height="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<MediaElement x:Name="MediaElementSetting"
Margin="16" />
<Border x:Name="AudioElement"
Margin="16"
Background="Red"
Visibility="Collapsed">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"
Text="AUDIO" />
</Border>
<Button x:Name="FileButton"
Grid.Row="1"
Margin="16"
Padding="8,4"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="FileButton_OnClick"
Content="File" />
</Grid>
</Window>
这是 code-behind。
我在 window 的构造函数中初始化 MediaElement
一次。
为了显示视频的第一帧,我需要设置ScrubbingEnabled = true
。
在 OpenFileDialog()
中,设置 Source
后我调用 SetupMedia
,它立即调用 Play
、Pause
,然后设置 Position
.这确保 MediaOpened
事件被调用。
在 OnMediaOpened
处理程序中,我调用 GetMediaInfo
就像您的 AV
函数,而不是 returning 一个整数,我 return改为枚举。
MainWindow.xaml.cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
namespace SO
{
public partial class MainWindow : Window
{
private bool isMediaOpened;
public MainWindow()
{
InitializeComponent();
MediaElementSetting.LoadedBehavior = MediaState.Manual;
MediaElementSetting.ScrubbingEnabled = true;
MediaElementSetting.UnloadedBehavior = MediaState.Close;
MediaElementSetting.MediaOpened += OnMediaOpened;
}
private void OnMediaOpened(object sender, RoutedEventArgs e)
{
isMediaOpened = true;
var mediaInfo = GetMediaInfo();
Debug.WriteLine($"{mediaInfo}");
}
private void SetupMedia()
{
MediaElementSetting.Play();
MediaElementSetting.Pause();
MediaElementSetting.Position = TimeSpan.FromSeconds(0);
}
private MediaInfo GetMediaInfo()
{
var mediaInfo = MediaInfo.None;
if (MediaElementSetting.NaturalDuration.HasTimeSpan)
{
if (MediaElementSetting.HasAudio)
{
mediaInfo = MediaElementSetting.HasVideo ? MediaInfo.VideoWithSound : MediaInfo.Audio;
}
else
{
if (MediaElementSetting.HasVideo)
{
mediaInfo = MediaInfo.VideoNoSound;
}
}
}
else
{
if (MediaElementSetting.HasVideo)
{
mediaInfo = MediaInfo.Image;
}
}
AudioElement.Visibility = mediaInfo == MediaInfo.Audio ? Visibility.Visible : Visibility.Collapsed;
return mediaInfo;
}
private void FileButton_OnClick(object sender, RoutedEventArgs e)
{
OpenFileDialog();
}
private void OpenFileDialog()
{
var dialog = new OpenFileDialog();
dialog.ShowDialog();
if (!string.IsNullOrEmpty(dialog.FileName))
{
if (isMediaOpened)
{
MediaElementSetting.Source = null;
isMediaOpened = false;
}
MediaElementSetting.Source = new Uri(dialog.FileName, UriKind.RelativeOrAbsolute);
SetupMedia();
}
}
public enum MediaInfo
{
None = 0,
Image = 1,
Audio = 2,
VideoNoSound = 3,
VideoWithSound = 4
}
}
}
好吧,我无意中找到了解决方案,非常适合我。 不要使用 MediaElement.LoadedBehavior = 完全不使用手册
Private Sub MediaElementSetting_MediaOpened(sender As Object, e As RoutedEventArgs) Handles MediaElementSetting.MediaOpened
Dim t As Integer = AV()
Me.MediaElementSetting.UnloadedBehavior = MediaState.Close
Me.MediaElementSetting.LoadedBehavior = MediaState.Play
Me.MediaElementSetting.LoadedBehavior = MediaState.Pause
End Sub
并使用 MediaElement.LoadedBehavior 控制媒体。这对我来说非常有效,即使我认为它不正确。从逻辑上讲,LoadedBehavior 表示加载的行为。
Sub PlayMedia()
MediaElementSetting.LoadedBehavior = MediaState.Play
End Sub
Sub PauseMedia()
MediaElementSetting.LoadedBehavior = MediaState.Pause
End Sub
Sub StopMedia()
MediaElementSetting.LoadedBehavior = MediaState.Stop
End Sub
我正在用 VB.NET 代码在 WPF 中创建一个简单的应用程序。此代码完美运行。选择文件后,函数returns根据媒体类型正确编号,当媒体是音频文件时出现音符图像,否则消失。媒体自动播放。但是我不需要自动播放媒体,当我将 LoadedBehavior 设置为手动(而不是默认播放)时,奇怪的事情发生了。 MediaOpened 事件会不时触发,函数 returns 有时为零,有时是正确的数字,有时是错误的数字。我在谷歌上搜索了将近三天,但一无所获。我想让 MediaElement.Play 和 MediaElement.Pause 显示 video/image 的第一帧,但如果没有将 LoadedBehavior 设置为手动,这是不可能的。我想以某种方式避免 LoadedBehavior。有人可以给我提示吗?非常感谢您。
Private Sub btnFile_Click(sender As Object, e As RoutedEventArgs) Handles btnFile.Click
Try
Me.MediaElementSetting.LoadedBehavior = MediaState.Manual
Me.MediaElementSetting.UnloadedBehavior = MediaState.Close
Me.MediaElementSetting.Stop()
Me.MediaElementSetting.Close()
Me.PvwTimer.Stop()
Catch ex As Exception
'The exception occurs when LoadedBehavior is not set to manual, that's why it's unused
'MsgBox(ex.ToString)
End Try
Dim ArrayIndes as Integer = 1
OpenFileDialog(ArrayIndex)
End Sub
Sub OpenFileDialog(ByVal ArrayIndex As Integer)
Dim Dlg1 As New System.Windows.Forms.OpenFileDialog
Dlg1.ShowDialog()
If Dlg1.FileName <> "" Then
strFile = Dlg1.FileName
Me.MediaElementSetting.Source = New Uri(strFile, UriKind.RelativeOrAbsolute)
End If
End Sub
Private Sub MediaElementSetting_MediaOpened(sender As Object, e As RoutedEventArgs) Handles MediaElementSetting.MediaOpened
Dim t As Integer = AV()
End Sub
Function AV() As Integer
'Check, if the media has timespan (if it is image, audio, video w sound, video w/o sound - image has video without timespan)
If Me.MediaElementSetting.NaturalDuration.HasTimeSpan = True Then
If Me.MediaElementSetting.HasAudio = True Then
If Me.MediaElementSetting.HasVideo = True Then
'Media is a video with sound
MediaInfo = 4
Else
'Media is an audio
MediaInfo = 2
End If
Else
If Me.MediaElementSetting.HasVideo = True Then
'Media is a video without sound
MediaInfo = 3
End If
End If
Else
If Me.MediaElementSetting.HasVideo = True Then
'Media is an image
MediaInfo = 1
End If
End If
If MediaInfo = 2 Then
'Note is an image in a window. When the media is an audio it covers the mediaelement in a window
Note.Visibility = Visibility.Visible
Else
Note.Visibility = Visibility.Hidden
End If
Return MediaInfo
End Function
我不是 VB.NET 人,但这是 C# 中的一个工作示例。
这是 XAML。我有一个 MediaElement
,一个 Border
作为笔记图像的 stand-in,还有一个按钮。
MainWindow.xaml
<Window x:Class="SO.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SO"
Title="MainWindow"
Width="800"
Height="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<MediaElement x:Name="MediaElementSetting"
Margin="16" />
<Border x:Name="AudioElement"
Margin="16"
Background="Red"
Visibility="Collapsed">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"
Text="AUDIO" />
</Border>
<Button x:Name="FileButton"
Grid.Row="1"
Margin="16"
Padding="8,4"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="FileButton_OnClick"
Content="File" />
</Grid>
</Window>
这是 code-behind。
我在 window 的构造函数中初始化 MediaElement
一次。
为了显示视频的第一帧,我需要设置ScrubbingEnabled = true
。
在 OpenFileDialog()
中,设置 Source
后我调用 SetupMedia
,它立即调用 Play
、Pause
,然后设置 Position
.这确保 MediaOpened
事件被调用。
在 OnMediaOpened
处理程序中,我调用 GetMediaInfo
就像您的 AV
函数,而不是 returning 一个整数,我 return改为枚举。
MainWindow.xaml.cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
namespace SO
{
public partial class MainWindow : Window
{
private bool isMediaOpened;
public MainWindow()
{
InitializeComponent();
MediaElementSetting.LoadedBehavior = MediaState.Manual;
MediaElementSetting.ScrubbingEnabled = true;
MediaElementSetting.UnloadedBehavior = MediaState.Close;
MediaElementSetting.MediaOpened += OnMediaOpened;
}
private void OnMediaOpened(object sender, RoutedEventArgs e)
{
isMediaOpened = true;
var mediaInfo = GetMediaInfo();
Debug.WriteLine($"{mediaInfo}");
}
private void SetupMedia()
{
MediaElementSetting.Play();
MediaElementSetting.Pause();
MediaElementSetting.Position = TimeSpan.FromSeconds(0);
}
private MediaInfo GetMediaInfo()
{
var mediaInfo = MediaInfo.None;
if (MediaElementSetting.NaturalDuration.HasTimeSpan)
{
if (MediaElementSetting.HasAudio)
{
mediaInfo = MediaElementSetting.HasVideo ? MediaInfo.VideoWithSound : MediaInfo.Audio;
}
else
{
if (MediaElementSetting.HasVideo)
{
mediaInfo = MediaInfo.VideoNoSound;
}
}
}
else
{
if (MediaElementSetting.HasVideo)
{
mediaInfo = MediaInfo.Image;
}
}
AudioElement.Visibility = mediaInfo == MediaInfo.Audio ? Visibility.Visible : Visibility.Collapsed;
return mediaInfo;
}
private void FileButton_OnClick(object sender, RoutedEventArgs e)
{
OpenFileDialog();
}
private void OpenFileDialog()
{
var dialog = new OpenFileDialog();
dialog.ShowDialog();
if (!string.IsNullOrEmpty(dialog.FileName))
{
if (isMediaOpened)
{
MediaElementSetting.Source = null;
isMediaOpened = false;
}
MediaElementSetting.Source = new Uri(dialog.FileName, UriKind.RelativeOrAbsolute);
SetupMedia();
}
}
public enum MediaInfo
{
None = 0,
Image = 1,
Audio = 2,
VideoNoSound = 3,
VideoWithSound = 4
}
}
}
好吧,我无意中找到了解决方案,非常适合我。 不要使用 MediaElement.LoadedBehavior = 完全不使用手册
Private Sub MediaElementSetting_MediaOpened(sender As Object, e As RoutedEventArgs) Handles MediaElementSetting.MediaOpened
Dim t As Integer = AV()
Me.MediaElementSetting.UnloadedBehavior = MediaState.Close
Me.MediaElementSetting.LoadedBehavior = MediaState.Play
Me.MediaElementSetting.LoadedBehavior = MediaState.Pause
End Sub
并使用 MediaElement.LoadedBehavior 控制媒体。这对我来说非常有效,即使我认为它不正确。从逻辑上讲,LoadedBehavior 表示加载的行为。
Sub PlayMedia()
MediaElementSetting.LoadedBehavior = MediaState.Play
End Sub
Sub PauseMedia()
MediaElementSetting.LoadedBehavior = MediaState.Pause
End Sub
Sub StopMedia()
MediaElementSetting.LoadedBehavior = MediaState.Stop
End Sub