我正在使用ValueConverter获取m4文件的缩略图,该文件是通过WinRT的MediaCapture直接录制的。经过大量的调试和替代方法,我已经确定了下面的转换器代码。我在GetThumbnailAsync方法上得到以下错误The component cannot be found. (Exception from HRESULT: 0x88982F50)
。
我已经确认,当我使用CopyTo(KnownFolders.VideosLibrary)时,Xbox视频应用程序和文件资源管理器应用程序中的视频缩略图正在显示。
当它是一个外部视频文件时,转换器似乎工作得很好,但与我的应用程序的mp4不兼容。我的转换器有问题吗?或者你能复制一下吗?
SEE UPDATE 1第一次创建文件时,我试图获取缩略图,但出现了同样的错误。
public class ThumbnailToBitmapImageConverter : IValueConverter
{
readonly StorageFolder localFolder = ApplicationData.Current.LocalFolder;
BitmapImage image;
public object Convert(object value, Type targetType, object parameter, string language)
{
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
return "images/ExamplePhoto2.jpg";
if (value == null)
return "";
var fileName = (string)value;
if (string.IsNullOrEmpty(fileName))
return "";
var bmi = new BitmapImage();
bmi.SetSource(Thumb(fileName).Result);
return bmi;
}
private async Task<StorageItemThumbnail> Thumb(string fileName)
{
try
{
var file = await localFolder.GetFileAsync(fileName)
.AsTask().ConfigureAwait(false);
var thumbnail = await file.GetScaledImageAsThumbnailAsync(ThumbnailMode.ListView, 90, ThumbnailOptions.UseCurrentScale)
.AsTask().ConfigureAwait(false);
return thumbnail;
}
catch (Exception ex)
{
new MessageDialog(ex.Message).ShowAsync();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
更新1
我决定回到我将视频保存到文件中的位置,在那里获取缩略图,然后将其保存到图像中以供以后使用。我得到了同样的错误,以下是视频保存后抓取和保存缩略图的代码:
var thumb = await videoStorageFile.GetThumbnailAsync(ThumbnailMode.ListView);
var buffer = new Windows.Storage.Streams.Buffer(Convert.ToUInt32(thumb.Size));
var thumbBuffer = await thumb.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
using (var str = await thumbImageFile.OpenAsync(FileAccessMode.ReadWrite))
{
await str.WriteAsync(thumbBuffer);
}
我还没有测试过,但它应该可以工作。在绑定到的模型中,将缩略图的属性替换为名为thumbnail的新类。绑定到该属性,而不是您的视频位置。当视频位置更改时,创建一个新的缩略图。
public class VideoViewModel : INotifyPropertyChanged
{
public string VideoLocation
{
get { return _location; }
set
{
_location = value;
Thumbnail = new Thumbnail(value);
OnPropertyChanged();
}
}
public Thumbnail Thumbnail
{
get { return _thumbnail; }
set
{
_thumbnail = value;
OnPropertyChanged();
}
}
}
缩略图类。这只是一个外壳,准备好让你填写剩下的
public class Thumbnail : INotifyPropertyChanged
{
public Thumbnail(string location)
{
Image = GetThumbFromVideoAsync(location);
}
private Task<BitMapSource> GetThumbFromVideoAsync(string location)
{
BitMapSource result;
// decode
// set it again to force
Image = Task.FromResult(result);
}
public Task<BitMapSource> Image
{
get { return _image; }
private set
{
_image = value;
OnPropertyChanged();
}
}
}
您仍然可以在适当的位置设置一个值转换器。它将检查任务是否已完成,如果尚未完成,则显示一些默认图像。如果任务出现故障,它可能会显示一些错误图像:
public class ThumbnailToBitmapImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var thumbnail = value as Thumbnail;
if (thumbnail == null) return GetDefaultBitmap();
if (thumbnail.Image.IsCompleted == false) return GetDefaultBitmap();
if (thumbnail.Image.IsFaulted) return GetBadImage();
return thumbnail.Image.Result;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
private BitMapSource GetDefaultBitmap()
{
// load a default image
}
private BitMapSource GetBadImage()
{
// load a ! image
}
}