转换器定义的 WPF MediaElement 源抛出 NullException
WPF MediaElement source defined by converter throw NullException
我有这个转换器:
public class MediaSourceConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || value.ToString().Trim() == "" || value.ToString() == "0")
{
// This case is running well
return null;
}
else
{
string link = value.ToString();
if (link.StartsWith("plugin://plugin.video.youtube/?action=play_video&videoid="))
{
// This case throw Null Exception in main windows code
return ("https://www.youtube.com/watch?v=" + link.Substring(link.LastIndexOf('=') + 1));
}
else if (link.StartsWith("http://") || link.StartsWith("https://"))
{
// This case is running well
return link;
}
else
{
// This case throw Null Exception in main windows code
return ("https://www.youtube.com/watch?v=" + link);
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML 是
<MediaElement x:Name="media_Player"
Source="{Binding SelectedItem.Key, ElementName=lv_Medias, Converter={StaticResource MediaSourceConverter}}"
Width="322" Height="181" />
当转换器 return a link with youtube 时,主 window 代码抛出 Null 异常。 link 始终有效,并且是从网络 api.
中检索到的
如果我删除 MediaElement 绑定中的转换器,当 link 以 http* 开头时媒体播放良好,当然,在其他情况下不播放但不会抛出错误。
有什么想法吗?
谢谢
问题是 MediaElement 需要 link 媒体文件(例如 MP4 文件),而您给它的是 Youtube 页面。虽然 Youtube 页面上确实有视频在播放,但它本身并不是视频文件
我会为那些可能对我如何处理这个问题感兴趣的人回答我自己的问题(我只需要基本的视频控制)
除了 mp4 link 我没有其他文件,除了 youtube
没有其他来源
string link = ""; // direct mp4 (or others) video link
string source = ""; // youtube link
if (dataSource.Key.StartsWith("plugin://plugin.video.youtube/?action=play_video&videoid="))
{
source = "https://www.youtube-nocookie.com/embed/" + dataSource.Key.Substring(dataSource.Key.LastIndexOf('=') + 1) + "?rel=0&showinfo=0";
}
else if (dataSource.Key.StartsWith("http://") || dataSource.Key.StartsWith("https://"))
{
link = dataSource.Key;
}
else
{
source = "https://www.youtube-nocookie.com/embed/" + dataSource.Key + "?rel=0&showinfo=0";
}
if (link == "")
{
wb_VideoPlayer.Source = new Uri(source);
}
else
{
wb_VideoPlayer.NavigateToString(@"<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=unicode' />
<meta http-equiv='X-UA-Compatible' content='IE=10' />
<title></title>
<style>
html {
-ms-overflow-style: none; /* For Internet Explorer and Edge */
}
body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div>
<video id='player' controls='' preload='metadata' width='421' height='237'>
<source src='" + link + @"' type='video/mp4' />
</video>
</div>
<script type='text/javascript'>
var v = document.getElementById('player');
var firstDisplayed = true;
// Sets the default time to 1 second to have a picture displayed
v.addEventListener('canplay', function() {
this.currentTime = 1;
});
v.addEventListener('play', function() {
if (firstDisplayed)
{
firstDisplayed = false;
v.currentTime = 0;
}
v.play();
});
v.addEventListener('ended', function() {
firstDisplayed = true;
v.pause();
v.currentTime = 1;
});
</script>
</body>
</html>");
}
在 XAML 中:
<Border HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,28,0,0"
Width="423" Height="239" Background="Black">
<WebBrowser x:Name="wb_VideoPlayer"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden" />
</Border>
我有这个转换器:
public class MediaSourceConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || value.ToString().Trim() == "" || value.ToString() == "0")
{
// This case is running well
return null;
}
else
{
string link = value.ToString();
if (link.StartsWith("plugin://plugin.video.youtube/?action=play_video&videoid="))
{
// This case throw Null Exception in main windows code
return ("https://www.youtube.com/watch?v=" + link.Substring(link.LastIndexOf('=') + 1));
}
else if (link.StartsWith("http://") || link.StartsWith("https://"))
{
// This case is running well
return link;
}
else
{
// This case throw Null Exception in main windows code
return ("https://www.youtube.com/watch?v=" + link);
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML 是
<MediaElement x:Name="media_Player"
Source="{Binding SelectedItem.Key, ElementName=lv_Medias, Converter={StaticResource MediaSourceConverter}}"
Width="322" Height="181" />
当转换器 return a link with youtube 时,主 window 代码抛出 Null 异常。 link 始终有效,并且是从网络 api.
中检索到的如果我删除 MediaElement 绑定中的转换器,当 link 以 http* 开头时媒体播放良好,当然,在其他情况下不播放但不会抛出错误。
有什么想法吗?
谢谢
问题是 MediaElement 需要 link 媒体文件(例如 MP4 文件),而您给它的是 Youtube 页面。虽然 Youtube 页面上确实有视频在播放,但它本身并不是视频文件
我会为那些可能对我如何处理这个问题感兴趣的人回答我自己的问题(我只需要基本的视频控制) 除了 mp4 link 我没有其他文件,除了 youtube
没有其他来源string link = ""; // direct mp4 (or others) video link
string source = ""; // youtube link
if (dataSource.Key.StartsWith("plugin://plugin.video.youtube/?action=play_video&videoid="))
{
source = "https://www.youtube-nocookie.com/embed/" + dataSource.Key.Substring(dataSource.Key.LastIndexOf('=') + 1) + "?rel=0&showinfo=0";
}
else if (dataSource.Key.StartsWith("http://") || dataSource.Key.StartsWith("https://"))
{
link = dataSource.Key;
}
else
{
source = "https://www.youtube-nocookie.com/embed/" + dataSource.Key + "?rel=0&showinfo=0";
}
if (link == "")
{
wb_VideoPlayer.Source = new Uri(source);
}
else
{
wb_VideoPlayer.NavigateToString(@"<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=unicode' />
<meta http-equiv='X-UA-Compatible' content='IE=10' />
<title></title>
<style>
html {
-ms-overflow-style: none; /* For Internet Explorer and Edge */
}
body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div>
<video id='player' controls='' preload='metadata' width='421' height='237'>
<source src='" + link + @"' type='video/mp4' />
</video>
</div>
<script type='text/javascript'>
var v = document.getElementById('player');
var firstDisplayed = true;
// Sets the default time to 1 second to have a picture displayed
v.addEventListener('canplay', function() {
this.currentTime = 1;
});
v.addEventListener('play', function() {
if (firstDisplayed)
{
firstDisplayed = false;
v.currentTime = 0;
}
v.play();
});
v.addEventListener('ended', function() {
firstDisplayed = true;
v.pause();
v.currentTime = 1;
});
</script>
</body>
</html>");
}
在 XAML 中:
<Border HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,28,0,0"
Width="423" Height="239" Background="Black">
<WebBrowser x:Name="wb_VideoPlayer"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden" />
</Border>