问题描述
我正在WPF中创建一个简单的应用,后面带有VB.NET代码。此代码完美地工作。选择文件后,该功能会根据媒体类型返回正确的数字,当媒体为音频文件时,便笺图像会出现,否则会消失。媒体自动播放。但是,我不需要自动播放媒体,并且当我将LoadedBehavior设置为“手动”(而不是默认的“播放”)时,会发生奇怪的事情。 MediaOpened事件不时被触发,该函数有时返回零,有时返回正确的数字,有时返回错误的数字。我已经搜寻了将近三天,却一无所获。我想让MediaElement.Play和MediaElement.Pause显示视频/图像的第一帧,但是如果不将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
作为笔记图像的替代品以及一个按钮。
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>
这是背后的代码。
我正在窗口的构造函数中初始化MediaElement
。
为了显示视频的第一帧,我需要设置ScrubbingEnabled = true
。
在OpenFileDialog()
中,设置Source
后,我调用SetupMedia
,后者立即调用Play
,Pause
,然后设置Position
。这样可以确保调用MediaOpened
事件。
在OnMediaOpened
处理程序中,我调用GetMediaInfo
,就像您的AV
函数一样,我没有返回整数,而是返回了一个枚举。
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