C# 如何保存媒体元素';什么是当前帧?

C# 如何保存媒体元素';什么是当前帧?,c#,uwp,C#,Uwp,我正在开发像vlc这样的媒体播放器。它的一个功能是在播放过程中保存快照。我能够使用以下c代码,使用rendertargetbitmap类成功保存任何元素的快照 但它不允许捕获媒体元素。请帮我解决一下。我猜,我不确定,是否可以使用StorageItemThumbnail类的位置从特定位置提取缩略图。即使如此,它将是一个缩略图,而不是当前帧的图像。谁来帮忙。这是我的应用程序的基本功能 在我开发的数字看板uwp应用程序中,我也有类似的要求。在网上搜索“我能做什么”时,我发现在UWP中,由于保护策略,您

我正在开发像vlc这样的媒体播放器。它的一个功能是在播放过程中保存快照。我能够使用以下c代码,使用rendertargetbitmap类成功保存任何元素的快照


但它不允许捕获媒体元素。请帮我解决一下。我猜,我不确定,是否可以使用StorageItemThumbnail类的位置从特定位置提取缩略图。即使如此,它将是一个缩略图,而不是当前帧的图像。谁来帮忙。这是我的应用程序的基本功能

在我开发的数字看板uwp应用程序中,我也有类似的要求。在网上搜索“我能做什么”时,我发现在UWP中,由于保护策略,您无法直接拍摄媒体元素的屏幕截图(例如,您可以创建一个小应用程序,在没有DRM管理的情况下捕获视频文件的所有帧)

我想出了一个解决办法:我将视频文件放在本地,这样我可以在某个点提取单个帧,并将其保存到磁盘上,与屏幕上呈现的视频尺寸相同(这样我就有了帧的完整图像供以后使用)。为此,我编写了以下函数:

private async Task<string> Capture(StorageFile file, TimeSpan timeOfFrame, Size imageDimension)
{
    if (file == null)
{
    return null;
}

//Get FrameWidth & FrameHeight
List<string> encodingPropertiesToRetrieve = new List<string>();
encodingPropertiesToRetrieve.Add("System.Video.FrameHeight");
encodingPropertiesToRetrieve.Add("System.Video.FrameWidth");
IDictionary<string, object> encodingProperties = await file.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve);
uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"];
uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"];

//Get image stream
var clip = await MediaClip.CreateFromFileAsync(file);
var composition = new MediaComposition();
composition.Clips.Add(clip);
var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame);

//Create BMP
var writableBitmap = new WriteableBitmap((int)frameWidth, (int)frameHeight);
writableBitmap.SetSource(imageStream);

//Get stream from BMP
string mediaCaptureFileName = "IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg";
var saveAsTarget = await CreateMediaFile(mediaCaptureFileName);
Stream stream = writableBitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);

using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, writeStream);
    encoder.SetPixelData(
        BitmapPixelFormat.Bgra8,
        BitmapAlphaMode.Premultiplied,
        (uint)writableBitmap.PixelWidth,
        (uint)writableBitmap.PixelHeight,
        96,
        96,
        pixels);
    await encoder.FlushAsync();                
    using (var outputStream = writeStream.GetOutputStreamAt(0))
    {
        await outputStream.FlushAsync();
    }
}
return saveAsTarget.Name;
}

嗨,阿戈斯蒂尼,谢谢你的帮助。它会一直平滑,直到无法识别\u mediaEngine@MgBhadurudeen我已经用正确的代码更新了我的答案。现在,它应该像预期的那样工作。让我知道!真是太棒了!感谢菲利波·阿戈斯蒂尼分享你的伟大知识@FilippoAgostini为什么不在GitHub中创建此示例(非常棒的工作;)谢谢你@shubhamashu!这几天我会按照你的建议在GitHub上放点东西!
private async Task<string> Capture(StorageFile file, TimeSpan timeOfFrame, Size imageDimension)
{
    if (file == null)
{
    return null;
}

//Get FrameWidth & FrameHeight
List<string> encodingPropertiesToRetrieve = new List<string>();
encodingPropertiesToRetrieve.Add("System.Video.FrameHeight");
encodingPropertiesToRetrieve.Add("System.Video.FrameWidth");
IDictionary<string, object> encodingProperties = await file.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve);
uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"];
uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"];

//Get image stream
var clip = await MediaClip.CreateFromFileAsync(file);
var composition = new MediaComposition();
composition.Clips.Add(clip);
var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame);

//Create BMP
var writableBitmap = new WriteableBitmap((int)frameWidth, (int)frameHeight);
writableBitmap.SetSource(imageStream);

//Get stream from BMP
string mediaCaptureFileName = "IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg";
var saveAsTarget = await CreateMediaFile(mediaCaptureFileName);
Stream stream = writableBitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);

using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, writeStream);
    encoder.SetPixelData(
        BitmapPixelFormat.Bgra8,
        BitmapAlphaMode.Premultiplied,
        (uint)writableBitmap.PixelWidth,
        (uint)writableBitmap.PixelHeight,
        96,
        96,
        pixels);
    await encoder.FlushAsync();                
    using (var outputStream = writeStream.GetOutputStreamAt(0))
    {
        await outputStream.FlushAsync();
    }
}
return saveAsTarget.Name;
}
public async Task<StorageFile> CreateMediaFile(string filename)
    {
        StorageFolder _mediaFolder = KnownFolders.PicturesLibrary;
        return await _mediaFolder.CreateFileAsync(filename);
    }