gpt4 book ai didi

c++ - 如何从 WinRT (8.1) 中的 MediaElement 捕获当前帧?

转载 作者:太空狗 更新时间:2023-10-29 21:01:02 24 4
gpt4 key购买 nike

我正在尝试在通过 MediaElement 显示视频的 WinRT 应用程序中实现屏幕截图功能。我有以下代码,它保存了 MediaElement 大小的屏幕截图,但图像是空的(全黑)。尝试使用各种类型的媒体文件。如果我在 Surface RT 上按 Win Key + Vol Down,屏幕截图包括媒体框架内容,但如果我使用以下代码,周围一片漆黑:(

private async Task SaveCurrentFrame()
{
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(Player);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
MultimediaItem currentItem = (MultimediaItem)this.DefaultViewModel["Group"];
StorageFolder currentFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
var saveFile = await currentFolder.CreateFileAsync(currentItem.UniqueId + ".png", CreationCollisionOption.ReplaceExisting);
if (saveFile == null)
return;
// Encode the image to the selected file on disk
using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);

encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
pixelBuffer.ToArray());

await encoder.FlushAsync();
}
}

这里的 MultimediaItem 是我的 View Model 类,它有一个 UniqueId 属性,它是一个字符串。

'Player' 是媒体元素的名称。

代码有什么问题或这种方法是错误的,我必须进入 C++ 战壕吗?

附言我只对 WinRT API 感兴趣。

更新 1 看起来 RenderTargetBitmap 不支持这个,MSDN 文档对此进行了澄清 http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.imaging.rendertargetbitmap .对于如何使用 DirectX C++ 执行此操作的任何指示,我将不胜感激。这对我来说是一项重大任务,因此我将以一种或另一种方式解决这个问题并报告解决方案。

最佳答案

是的,这是可能的 - 有点棘手,但效果很好。

您不使用 mediaElement,而是使用 StorageFile 本身。您需要在 Windows.Media.Editing 的帮助下创建 writableBitmap命名空间。

适用于 UWP (Windows 10)

这是一个完整的示例,包括文件选择、获取视频分辨率以及将图像保存到图片库

        TimeSpan timeOfFrame = new TimeSpan(0, 0, 1);//one sec

//pick mp4 file
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".mp4");
StorageFile pickedFile = await picker.PickSingleFileAsync();
if (pickedFile == null)
{
return;
}
///


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


//Use Windows.Media.Editing to get ImageStream
var clip = await MediaClip.CreateFromFileAsync(pickedFile);
var composition = new MediaComposition();
composition.Clips.Add(clip);

var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame);
///


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


//generate some random name for file in PicturesLibrary
var saveAsTarget = await KnownFolders.PicturesLibrary.CreateFileAsync("IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg");


//get stream from bitmap
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();
}
}

是的...我为此花了很多时间

关于c++ - 如何从 WinRT (8.1) 中的 MediaElement 捕获当前帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19871443/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com