'MediaElement.SetSource()' 更新不一致
'MediaElement.SetSource()' isn't updating consistently
我的程序应该在用户按下 'Play' 按钮时播放视频。虽然它通常会这样做,但他们第一次按下 'Play' 按钮时什么也不会发生。
我已将此错误追溯到以下代码,它设置了我的 MediaElement 'VideoPlayer':
public void playVideo_Tapped(object sender, TappedRoutedEventArgs e)
{
setUpVideo();
VideoPlayer.Play();
}
public async void setUpVideo()
{
if(vm == null) return;
StorageFile videoFile = vm.videoFile;
if (videoFile == null || !videoFile.ContentType.Equals("video/mp4")) return;
using (IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read))
{
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
}
}
罪魁祸首似乎是最后的 'SetSource()' 方法。从第一次单击 'Play' 到下一次单击唯一变化的变量是变量 'VideoPlayer.PlayToSource',它从 null 更改为实际值。
(作为旁注,变量 'VideoPlayer.CurrentState' 也从 'Closed' 更改为 'Opening' 但在第二次单击之前将自身重置为 'Closed'。只有 'PlayToSource' 改变了功能。)
我认为我可以通过在第一种方法中执行此操作来快速修复:
setUpVideo();
setUpVideo();
VideoPlayer.Play();
不是很好的代码,但它应该把事情弄清楚,对吧?没有!这会导致 NullReferenceException。在第二次调用 'setUpVideo()' 时,我发现 'PlayToSource' 仍然有一个值并且 'VideoPlayer.CurrentState' 仍然设置为 'Opening'... 以某种方式触发了 NullReferenceException。
我希望解决方案是以下之一:
1.) 在调用 'SetSource' 之前在第一次点击时设置 'VideoPlayer.PlayToSource'。
2.) 在快速修复中,在两次调用之间将 'VideoPlayer.CurrentState' 设置回 'Closed'。
3.) 模仿第一次点击的其他一些东西。
当然,我的两个想法都涉及更改只读变量。这就是我被困的地方。我将包括 .xaml 代码以备不时之需,但我相信方法 'SetSource' 是我的麻烦的根源:
<Grid x:Name="VideoViewerParentGrid" Background="DarkGreen" Height="{Binding VideoViewerParentGridHeight }" Width="{Binding VideoViewerParentGridWidth}">
<MediaElement x:Name="VideoPlayer" HorizontalAlignment="Center" VerticalAlignment="Bottom" Stretch="Uniform"
Visibility="{Binding VideoVisibility, Converter={StaticResource visibilityConverter}}"/>
<Button Style="{StaticResource BackButtonStyle}" Tapped="VideoViewerClose_Tapped" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button Name="Play_Button" Content="Play Video" FontSize="26" Tapped="playVideo_Tapped"
VerticalAlignment="Top" HorizontalAlignment="Left" Height="60" Width="180" Margin="0,80,0,0"/>
</Grid>
----更新----
一些更多的调查表明,在第一次点击时 'VideoPlayer.CurrentState' 永远不会达到 'Playing' 状态,而是从 'Opening' 直接回到 'Closed'。只要程序是 运行,它就不会对任何后续点击执行此操作。仍在调查此问题的原因。
您缺少 "await" 关键字。这样做:-
await setUpVideo();
简短版本,此问题已通过更改以下内容得到解决:
using (IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read))
{
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
}
...成为这样的:
IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read);
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
更长的版本,我的代码因错误 "mf_media_engine_err_src_not_supported hresult - 0xc00d36c4" 而失败,该错误正在关闭我的 MediaElement 而不是播放它。发生这种情况是因为当我离开 'using' 代码块时,'IRandomAccessStream' 会在我读取文件的过程中关闭。我不是 100% 清楚为什么它会在第一个 运行 代码之后完成整个过程,但至少它现在可以可靠地工作。
我还必须在应得的地方给予表扬,我在这里找到了这个答案:Windows 8 app - MediaElement not playing ".wmv" files
我的程序应该在用户按下 'Play' 按钮时播放视频。虽然它通常会这样做,但他们第一次按下 'Play' 按钮时什么也不会发生。
我已将此错误追溯到以下代码,它设置了我的 MediaElement 'VideoPlayer':
public void playVideo_Tapped(object sender, TappedRoutedEventArgs e)
{
setUpVideo();
VideoPlayer.Play();
}
public async void setUpVideo()
{
if(vm == null) return;
StorageFile videoFile = vm.videoFile;
if (videoFile == null || !videoFile.ContentType.Equals("video/mp4")) return;
using (IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read))
{
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
}
}
罪魁祸首似乎是最后的 'SetSource()' 方法。从第一次单击 'Play' 到下一次单击唯一变化的变量是变量 'VideoPlayer.PlayToSource',它从 null 更改为实际值。
(作为旁注,变量 'VideoPlayer.CurrentState' 也从 'Closed' 更改为 'Opening' 但在第二次单击之前将自身重置为 'Closed'。只有 'PlayToSource' 改变了功能。)
我认为我可以通过在第一种方法中执行此操作来快速修复:
setUpVideo();
setUpVideo();
VideoPlayer.Play();
不是很好的代码,但它应该把事情弄清楚,对吧?没有!这会导致 NullReferenceException。在第二次调用 'setUpVideo()' 时,我发现 'PlayToSource' 仍然有一个值并且 'VideoPlayer.CurrentState' 仍然设置为 'Opening'... 以某种方式触发了 NullReferenceException。
我希望解决方案是以下之一:
1.) 在调用 'SetSource' 之前在第一次点击时设置 'VideoPlayer.PlayToSource'。
2.) 在快速修复中,在两次调用之间将 'VideoPlayer.CurrentState' 设置回 'Closed'。
3.) 模仿第一次点击的其他一些东西。
当然,我的两个想法都涉及更改只读变量。这就是我被困的地方。我将包括 .xaml 代码以备不时之需,但我相信方法 'SetSource' 是我的麻烦的根源:
<Grid x:Name="VideoViewerParentGrid" Background="DarkGreen" Height="{Binding VideoViewerParentGridHeight }" Width="{Binding VideoViewerParentGridWidth}">
<MediaElement x:Name="VideoPlayer" HorizontalAlignment="Center" VerticalAlignment="Bottom" Stretch="Uniform"
Visibility="{Binding VideoVisibility, Converter={StaticResource visibilityConverter}}"/>
<Button Style="{StaticResource BackButtonStyle}" Tapped="VideoViewerClose_Tapped" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button Name="Play_Button" Content="Play Video" FontSize="26" Tapped="playVideo_Tapped"
VerticalAlignment="Top" HorizontalAlignment="Left" Height="60" Width="180" Margin="0,80,0,0"/>
</Grid>
----更新----
一些更多的调查表明,在第一次点击时 'VideoPlayer.CurrentState' 永远不会达到 'Playing' 状态,而是从 'Opening' 直接回到 'Closed'。只要程序是 运行,它就不会对任何后续点击执行此操作。仍在调查此问题的原因。
您缺少 "await" 关键字。这样做:-
await setUpVideo();
简短版本,此问题已通过更改以下内容得到解决:
using (IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read))
{
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
}
...成为这样的:
IRandomAccessStream fileStream = await videoFile.OpenAsync(FileAccessMode.Read);
VideoPlayer.SetSource(fileStream, videoFile.ContentType);
更长的版本,我的代码因错误 "mf_media_engine_err_src_not_supported hresult - 0xc00d36c4" 而失败,该错误正在关闭我的 MediaElement 而不是播放它。发生这种情况是因为当我离开 'using' 代码块时,'IRandomAccessStream' 会在我读取文件的过程中关闭。我不是 100% 清楚为什么它会在第一个 运行 代码之后完成整个过程,但至少它现在可以可靠地工作。
我还必须在应得的地方给予表扬,我在这里找到了这个答案:Windows 8 app - MediaElement not playing ".wmv" files