【发布时间】:2020-09-27 16:10:22
【问题描述】:
因此,我希望能够在录制视频时在前后摄像头之间切换,并且不会中断视频流。我注意到即使是 iOS 内置的相机应用程序也不会这样做,但我听说一些第三方应用程序会这样做。 下面是 xamarin.ios 中的示例代码。
AVCaptureMovieFileOutput movieFileOutput;
AVCaptureDevice CurrentCamera { get; set; }
AVCaptureDevice BackCamera { get; set; }
AVCaptureDevice FrontCamera { get; set; }
AVCaptureDevice Mic { get; set; }
bool HasBackCamera { get { return BackCamera != null; } }
bool HasFrontCamera { get { return FrontCamera != null; } }
bool HasMic { get { return Mic != null; } }
void SetDeviceProperties()
{
//Set up the devices
foreach(var device in AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video))
{
if(device.Position == AVCaptureDevicePosition.Back)
{
BackCamera = device;
}
else
{
FrontCamera = device;
}
}
Mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio);
}
public bool SwapCameras()
{
if(HasBackCamera && HasFrontCamera)
{
var nextCamera = CurrentCamera == BackCamera ? FrontCamera : BackCamera;
NSError error = null;
var newInput = new AVCaptureDeviceInput(nextCamera, out error);
if(error != null)
{
throw new Exception(error.ToString());
}
session.BeginConfiguration();
//Remove current video input
foreach(AVCaptureDeviceInput input in session.Inputs)
{
if(input.Device.HasMediaType(AVMediaType.Video))
{
session.RemoveInput(input);
}
}
if(session.CanAddInput(newInput))
{
session.AddInput(newInput);
}
session.CommitConfiguration();
CurrentCamera = nextCamera;
CameraConfigured(this, new TArgs<AVCaptureDevice>(CurrentCamera));
}
return CurrentCamera == FrontCamera;
}
下面是视频输出的配置
var layer = new AVCaptureVideoPreviewLayer (session);
layer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
var cameraView = new UIView ();
cameraView.Layer.AddSublayer (layer);
var filePath = Path.Combine (Path.GetTempPath (), "temporary.mov");
var fileUrl = NSUrl.FromFilename (filePath);
var movieFileOutput = new AVCaptureMovieFileOutput ();
var recordingDelegate = new MyRecordingDelegate ();
session.AddOutput (movieFileOutput);
movieFileOutput.StartRecordingToOutputFile (fileUrl, recordingDelegate);
录制停止时调用的委托(来自第一个会话的 removeInput):
public class MyRecordingDelegate : AVCaptureFileOutputRecordingDelegate
{
public override void FinishedRecording (AVCaptureFileOutput captureOutput, NSUrl outputFileUrl, NSObject [] connections, NSError error)
{
if (UIVideo.IsCompatibleWithSavedPhotosAlbum (outputFileUrl.Path))
{
var library = new ALAssetsLibrary ();
library.WriteVideoToSavedPhotosAlbum (outputFileUrl, (path, e2) =>
{
if (e2 != null)
{
new UIAlertView ("Error", e2.ToString (), null, "OK", null).Show ();
}
else
{
new UIAlertView ("Saved", "Saved to Photos", null, "OK", null).Show ();
File.Delete (outputFileUrl.Path);
}
});
}
else
{
new UIAlertView ("Incompatible", "Incompatible", null, "OK", null).Show ();
}
}
}
那么这真的可能吗?如果可以,我将如何更改上面的代码以在切换相机时不停止录制?
【问题讨论】:
-
多机位录制是在 iOS 13 中引入的,仅适用于“较新”的硬件型号,这包括对某些相机组合的一些限制。它使用了对 AVFoundation 框架的添加,因此您的代码虽然很好并且仍然推荐(Apple)用于单凸轮使用,但需要进行大量更改。我建议先查看 WWDC 视频:developer.apple.com/documentation/avfoundation/…,然后再查看文档和示例应用程序:developer.apple.com/videos/play/wwdc2019/249
标签: ios xamarin xamarin.forms xamarin.ios