如何以高效的方式从 RenderTargetBitmap 创建媒体剪辑?
How to create a MediaClip from RenderTargetBitmap in an efficent way?
我正在尝试使用 c# 在 UWP 应用中捕获 XAML 网格的视频。
我的方法。
1.Use RenderTargetBitmap 使用 renderTargetBitmap.RenderAsync
截屏
2.Convert数据到字节数组。
3.Create 具有字节的图像文件并使用 BitmapEncoder
将其保存在磁盘上
4.Create 来自该图像的 MediaClip 使用 MediaClip.CreateFromImageFileAsync
5.Add 剪辑到 MediaComposition composition.Clips.Add(clip)
6.Save 作为视频使用 composition.RenderToFileAsync(video);
现在这个方法行得通了。
但是你可以想象,去磁盘保存图像,然后读取它们来创建剪辑,它的 SLOWWWW 和帧率很低。
我正在寻找可以避免每个屏幕截图转到磁盘的东西。
将 RenderTargetBitmap
(或 IBuffer
或 byte[]
)转换为 MediaClip
的东西,无需进入磁盘,或使用其他方法保存视频。
我正在为 Hololens 开发 UWP 应用。
尝试这样的事情:
和你一样。
using (var soft = SoftwareBitmap.CreateCopyFromBuffer(pixels, BitmapPixelFormat.Bgra8, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, BitmapAlphaMode.Premultiplied))
{
CanvasBitmap canvas = CanvasBitmap.CreateFromSoftwareBitmap(CanvasDevice.GetSharedDevice(), soft);
MediaClip m = MediaClip.CreateFromSurface(canvas, DateTime.Now - previousFrame);
composition.Clips.Add(m);
}
记得捕获设备丢失异常并创建新设备
对于那些在尝试@Mediaarea 的答案时遇到异常的人,试试这个:
CanvasRenderTarget rendertarget = null;
using (CanvasBitmap canvas = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), pixel_buffer, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized))
{
rendertarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), canvas.SizeInPixels.Width, canvas.SizeInPixels.Height, 96);
using (CanvasDrawingSession ds = rendertarget.CreateDrawingSession())
{
ds.Clear(Colors.Black);
ds.DrawImage(canvas);
}
}
MediaClip m = MediaClip.CreateFromSurface(rendertarget, TimeSpan.FromMilliseconds(80));
mc.Clips.Add(m);
如果您使用它,错误 Stream is not in a state to handle the request 就会消失。
我正在尝试使用 c# 在 UWP 应用中捕获 XAML 网格的视频。
我的方法。
1.Use RenderTargetBitmap 使用 renderTargetBitmap.RenderAsync
2.Convert数据到字节数组。
3.Create 具有字节的图像文件并使用 BitmapEncoder
4.Create 来自该图像的 MediaClip 使用 MediaClip.CreateFromImageFileAsync
5.Add 剪辑到 MediaComposition composition.Clips.Add(clip)
6.Save 作为视频使用 composition.RenderToFileAsync(video);
现在这个方法行得通了。
但是你可以想象,去磁盘保存图像,然后读取它们来创建剪辑,它的 SLOWWWW 和帧率很低。
我正在寻找可以避免每个屏幕截图转到磁盘的东西。
将 RenderTargetBitmap
(或 IBuffer
或 byte[]
)转换为 MediaClip
的东西,无需进入磁盘,或使用其他方法保存视频。
我正在为 Hololens 开发 UWP 应用。
尝试这样的事情:
和你一样。
using (var soft = SoftwareBitmap.CreateCopyFromBuffer(pixels, BitmapPixelFormat.Bgra8, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, BitmapAlphaMode.Premultiplied))
{
CanvasBitmap canvas = CanvasBitmap.CreateFromSoftwareBitmap(CanvasDevice.GetSharedDevice(), soft);
MediaClip m = MediaClip.CreateFromSurface(canvas, DateTime.Now - previousFrame);
composition.Clips.Add(m);
}
记得捕获设备丢失异常并创建新设备
对于那些在尝试@Mediaarea 的答案时遇到异常的人,试试这个:
CanvasRenderTarget rendertarget = null;
using (CanvasBitmap canvas = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), pixel_buffer, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized))
{
rendertarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), canvas.SizeInPixels.Width, canvas.SizeInPixels.Height, 96);
using (CanvasDrawingSession ds = rendertarget.CreateDrawingSession())
{
ds.Clear(Colors.Black);
ds.DrawImage(canvas);
}
}
MediaClip m = MediaClip.CreateFromSurface(rendertarget, TimeSpan.FromMilliseconds(80));
mc.Clips.Add(m);
如果您使用它,错误 Stream is not in a state to handle the request 就会消失。