如何在HoloLens 2的Unity中显示MediaCapture API预览流?
在Unity/HoloLens 2中实现MediaCapture预览流的方案
在Unity环境下,并没有直接对应UWP中CaptureElement的原生控件,要实现MediaCapture的预览流展示,主要有两种可行方案:
方法一:使用Unity原生WebCamTexture(快速实现)
这是最简便的方式,Unity底层已经封装了WinRT的MediaCapture逻辑,无需直接调用原生API:
- 在场景中创建一个Plane或Quad作为预览画面的载体,添加
MeshRenderer组件 - 编写如下C#脚本并挂载到载体上:
using UnityEngine; public class CameraPreview : MonoBehaviour { private WebCamTexture webCamTexture; void Start() { // 遍历摄像头设备,选择HoloLens的前置RGB摄像头 WebCamDevice[] devices = WebCamTexture.devices; foreach (var device in devices) { if (device.isFrontFacing) { webCamTexture = new WebCamTexture(device.name); break; } } if (webCamTexture != null) { // 将摄像头纹理赋值给材质 GetComponent<Renderer>().material.mainTexture = webCamTexture; webCamTexture.Play(); } } void OnDestroy() { webCamTexture?.Stop(); } }
- 打包前需在Unity的Player Settings > UWP > Capabilities中勾选
WebCam权限,部署到HoloLens 2即可生效
方法二:通过WinRT互操作直接调用MediaCapture(自定义控制)
如果需要更精细的控制(比如自定义分辨率、获取原始帧数据做处理),可以直接调用WinRT的MediaCapture API,将捕获的帧转换为Unity纹理:
核心代码示例:
using UnityEngine; using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.Graphics.Imaging; using System.Threading.Tasks; using System.Runtime.InteropServices; public class MediaCapturePreview : MonoBehaviour { private MediaCapture mediaCapture; private Texture2D previewTexture; private byte[] frameBuffer; async void Start() { // 初始化MediaCapture mediaCapture = new MediaCapture(); await mediaCapture.InitializeAsync(); // 设置自定义预览分辨率 var previewProps = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; previewProps.Width = 1280; previewProps.Height = 720; await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, previewProps); // 创建匹配分辨率的Unity纹理 previewTexture = new Texture2D((int)previewProps.Width, (int)previewProps.Height, TextureFormat.BGRA32, false); frameBuffer = new byte[previewProps.Width * previewProps.Height * 4]; GetComponent<Renderer>().material.mainTexture = previewTexture; // 启动预览帧捕获循环 await StartPreviewCaptureLoop(); } private async Task StartPreviewCaptureLoop() { while (true) { using (var frame = await mediaCapture.GetPreviewFrameAsync()) { var bitmap = frame.SoftwareBitmap; // 将帧数据复制到字节数组 using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Read)) using (var reference = buffer.CreateReference()) { Marshal.Copy((IntPtr)reference, frameBuffer, 0, frameBuffer.Length); } // 更新Unity纹理 previewTexture.LoadRawTextureData(frameBuffer); previewTexture.Apply(); } await Task.Delay(16); // 控制帧率约60fps } } async void OnDestroy() { if (mediaCapture != null) { await mediaCapture.StopPreviewAsync(); mediaCapture.Dispose(); } Destroy(previewTexture); } }
注意事项:
- 需在Unity的Player Settings > Configuration > Scripting Runtime Version中选择
.NET 4.x Equivalent,才能支持WinRT API调用 - 打包前同样要在UWP Capabilities中勾选
WebCam和Microphone(MediaCapture默认依赖) - 帧捕获循环需注意线程调度,避免阻塞主线程
内容的提问来源于stack exchange,提问作者anjelomerte
相关产品推荐
相关产品推荐

