我正在使用ValueConverter来获取直接使用WinRT的 MediaCapture 记录的m4文件的缩略图。经过大量的调试和替代方法,我已经确定了下面的转换器代码。我在 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);
}
答案 0 :(得分:2)
我没有对此进行测试,但它应该可行。在要绑定到的模型中,使用名为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();
}
}
}
缩略图类。这只是一个shell,随时可以填写其余部分
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
}
}