添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

此命名空间包含音频和视频的高级录制和播放功能。

此库位于 CoreMedia、CoreAudio 和 CoreVideo 之上,但不为 UIKit 提供任何用户界面元素。 它是用于录制和播放音频和视频的工具包。

AV Foundation 广泛使用后台处理。 应用程序开发人员应注意确保线程安全,并在更新其用户界面时使用 InvokeOnMainThread 或其他技术。

某些常见任务不需要 AVFoundation:

任务 方法
显示视频 使用 Media Player 的 MPMoviePlayerController MPMoviePlayerViewController
捕获照片或视频 使用 UIKit 的 UIImagePickerController
播放音频文件 使用 AV Foundation 的 AVAudioPlayer
捕获音频文件 使用 AV Foundation 的 AVAudioRecorder ,如下面“捕获音频文件”中所述。
复杂的视频显示或音频播放 使用 AV Foundation,如下文“自定义播放”中所述。
自定义媒体捕获 使用 AV Foundation,如下文“自定义媒体捕获”中所述。
媒体文件写入、读取和转码 使用 AV Foundation,如下文“媒体文件写入、读取和转码”中所述。
媒体编辑 使用 UIKit 的 T:UIKit.UIVideoKitController 或 AV Foundation 构建基块。
条形码识别和人脸检测 使用 AV Foundation,如下文“实时识别”中所述。
语音合成 使用 AV Foundation,如下文“语音合成”中所述。

表示 AVAsset 一个或多个媒体资产。 这些都保存在其 Tracks 财产中。 此外, AVAsset 还包括元数据、跟踪分组和媒体首选项。

由于媒体资产(如电影)很大,因此实例化 AVAsset 不会自动加载文件。 查询属性时或通过对 或 LoadValuesAsynchronously 的显式调用 LoadValuesTaskAsync 加载属性。

捕获音频文件

应用程序开发人员必须首先与静态单一实例音频会话对象交互,该对象在应用和操作系统之间调节声音。 和 AVAudioSession AudioSession 引用此相同的基础单一实例。 中的 AudioSession 大多数属性在 iOS 7 及更高版本中已弃用,应用程序开发人员应首选 中的 AVAudioSession 属性。

任务 使用 AVAudioSession 使用 AudioSession
初始化 SharedInstance 不需要) (显式初始化

M:AudioToolbox.AudioSession.Initialize (CFRunLoop,string)

设置类别

M:AVFoundation.AVAudioSession.SetCategory (string,out NSError)

Category
设置活动

M:AVFoundation.AVAudioSession.SetActive (bool, out NSError)

P:AudioToolbox.AudioSession.Active

以下代码演示了准备音频录制的必要步骤。

var session = AVAudioSession.SharedInstance();
NSError error = null;
session.SetCategory(AVAudioSession.CategoryRecord, out error);
if(error != null){
	Console.WriteLine(error);
	return;
session.SetActive(true, out error);
if(error != null){
	Console.WriteLine(error);
	return;
//Declare string for application temp path and tack on the file extension
string fileName = string.Format("Myfile{0}.aac", DateTime.Now.ToString("yyyyMMddHHmmss"));
string tempRecording = NSBundle.MainBundle.BundlePath + "/../tmp/" + fileName;
Console.WriteLine(tempRecording);
this.audioFilePath = NSUrl.FromFilename(tempRecording);
var audioSettings = new AudioSettings() {
	SampleRate = 44100.0f, 
	Format = MonoTouch.AudioToolbox.AudioFormatType.MPEG4AAC,
	NumberChannels = 1,
	AudioQuality = AVAudioQuality.High
//Set recorder parameters
NSError error;
recorder = AVAudioRecorder.Create(this.audioFilePath, audioSettings, out error);
if((recorder == null) || (error != null))
	Console.WriteLine(error);
	return false;
//Set Recorder to Prepare To Record
if(!recorder.PrepareToRecord())
	recorder.Dispose();
	recorder = null;
	return false;
recorder.FinishedRecording += delegate (object sender, AVStatusEventArgs e) {
	recorder.Dispose();
	recorder = null;
	Console.WriteLine("Done Recording (status: {0})", e.Status);
recorder.Record();          
 

自定义播放

T:AVFoundation.Player 对象使用 AVPlayerItem 对象播放媒体。 封装 AVPlayerItem 的表示状态 AVAsset

自定义媒体捕获

许多捕获方案都对更易于使用的 UIImagePickerController AVAudioRecorder 类感到满意。 更复杂的方案可以使用 AV Foundation 和相关 AVCaptureSession 类。

AVCaptureSession 通常会有一个或多个 AVCaptureInput ,以及一个或多个 AVCaptureOutput 。 每个都会 AVCaptureInput 为特定媒体类型 (音频或视频) 。 AVCaptureDevice 每个 T:AVFoundation.AVCaptureOuput 都将具有一个“缓冲区委托”,该委托将重复调用它可呈现、写入文件、分析等传入数据。

下图和源代码显示了 的初始化序列

AVCaptureFrames 示例

session = new AVCaptureSession () {
	SessionPreset = AVCaptureSession.PresetMedium
// create a device input and attach it to the session
var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
if (captureDevice == null){
	Console.WriteLine ("No captureDevice - this won't work on the simulator, try a physical device");
	return false;
// If you want to cap the frame rate at a given speed, in this sample: 15 frames per second
NSError error = null;
captureDevice.LockForConfiguration(out error);
if(error != null){
	Console.WriteLine(error);
	captureDevice.UnlockForConfiguration();
	return false;
captureDevice.ActiveVideoMinFrameDuration = new CMTime(1, 15);
captureDevice.UnlockForConfiguration();
var input = AVCaptureDeviceInput.FromDevice (captureDevice);
if (input == null){
	Console.WriteLine ("No input - this won't work on the simulator, try a physical device");
	return false;
session.AddInput (input);
// create a VideoDataOutput and add it to the sesion
var output = new AVCaptureVideoDataOutput () {
	VideoSettings = new AVVideoSettings (CVPixelFormatType.CV32BGRA),
// configure the output
queue = new MonoTouch.CoreFoundation.DispatchQueue ("myQueue");
outputRecorder = new OutputRecorder ();
output.SetSampleBufferDelegate (outputRecorder, queue);
session.AddOutput (output);
session.StartRunning ();
 

请注意, outputRecorder 是 的 AVCaptureVideoDataOutputSampleBufferDelegate 自定义子类。 在这种情况下,传入数据将转换为 , CIImage CIColorInvert 在发送到显示器之前,将向其应用筛选器。

public class OutputRecorder : AVCaptureVideoDataOutputSampleBufferDelegate {
	readonly CIColorInvert filter;
	public OutputRecorder()
		filter = new CIColorInvert();
	public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
		try {
			var image = ImageFromSampleBuffer (sampleBuffer);
			filter.Image = image;
			// Do something with the image, we just stuff it in our main view.
			AppDelegate.ImageView.BeginInvokeOnMainThread (delegate {
				AppDelegate.ImageView.Image = UIImage.FromImage(filter.OutputImage);
			// Although this looks innocent "Oh, he is just optimizing this case away"
			// this is incredibly important to call on this callback, because the AVFoundation
			// has a fixed number of buffers and if it runs out of free buffers, it will stop
			// delivering frames. 
			sampleBuffer.Dispose ();
		} catch (Exception e){
			Console.WriteLine (e);
	CIImage ImageFromSampleBuffer (CMSampleBuffer sampleBuffer)
		// Get the CoreVideo image
		using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer){
			// Lock the base address
			pixelBuffer.Lock (0);
			// Get the number of bytes per row for the pixel buffer
			var baseAddress = pixelBuffer.BaseAddress;
			int bytesPerRow = pixelBuffer.BytesPerRow;
			int width = pixelBuffer.Width;
			int height = pixelBuffer.Height;
			var flags = CGBitmapFlags.PremultipliedFirst | CGBitmapFlags.ByteOrder32Little;
			// Create a CGImage on the RGB colorspace from the configured parameter above
			using (var cs = CGColorSpace.CreateDeviceRGB ())
			using (var context = new CGBitmapContext (baseAddress,width, height, 8, bytesPerRow, cs, (CGImageAlphaInfo) flags))
			using (var cgImage = context.ToImage ()){
				pixelBuffer.Unlock (0);
				return cgImage;
 

可以使用 直接将视频捕获到 文件中 AVCaptureMovieFileOutput 。 但是,此类没有可显示的数据,并且不能与 AVCaptureVideoDataOutput 同时使用。 相反,应用程序开发人员可以将它与 结合使用, AVCaptureVideoPreviewLayer 如以下示例所示:

var session = new AVCaptureSession();
var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
var  mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio);
if(camera == null || mic == null){
    throw new Exception("Can't find devices");
if(session.CanAddInput(camera)){
    session.AddInput(camera);
if(session.CanAddInput(mic)){
   session.AddInput(mic);
var layer = new AVCaptureVideoPreviewLayer(session);
layer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill;
layer.VideoGravity = AVCaptureVideoPreviewLayer.GravityResizeAspectFill;
var cameraView = new UIView();
cameraView.Layer.AddSublayer(layer);
var filePath = System.IO.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);
 

应用程序开发人员应注意,函数 T:AVFoundation.AVCaptureMovieFileOutput.StopRecording 是异步的;例如, FinishedRecording 开发人员应等到委托方法后再操作文件 (,然后再将其保存到包含 SaveToPhotosAlbum WriteVideoToSavedPhotosAlbumAsync ) 的相册。

媒体文件写入、读取和转码

以下是 iOS 7 支持音频格式的官方列表:

  • AAC
  • Apple Lossless (ALAC)
  • A-law
  • IMA/ADPCM (IMA4)
  • 线性 PCM
  • μ法
  • DVI/Intel IMA ADPCM
  • Microsoft GSM 6.10
  • AES3-2003

以及以下视频格式:

  • H.264 视频,最高 1.5 Mbps,640 x 480 像素,每秒 30 帧,Low-Complexity 版本的 H.264 基线配置文件,最高 160 Kbps、48 kHz、.m4v 立体声音频、.mp4 和 .mov 文件格式
  • H.264 视频,最大 768 Kbps,320 x 240 像素,30 帧/秒,基线配置文件高达 1.3 级,AAC-LC 音频高达 160 Kbps、48 kHz、.m4v、.mp4 和 .mov 文件格式的立体声音频
  • MPEG-4 视频,最大 2.5 Mbps,640 x 480 像素,30 帧/秒,简单配置文件,AAC-LC 音频最大 160 Kbps,48 kHz,.m4v 立体声音频,.mp4 和 .mov 文件格式

此列表不完整:例如,iPhone 5S 以 1280 x 720 本机捕获。

使用 读取媒体文件。 AVAssetReader 与许多 AV 基础类一样,这以异步方式提供数据。 属性 Outputs 包含 AVAssetReaderOutput 对象。 CopyNextSampleBuffer 这些对象上的 方法将定期调用,因为 处理 AVAssetReader 基础 Asset

可使用 编写媒体文件, AVAssetWriter 但在媒体捕获会话中,更常见的是使用 AVAudioRecorder AVCaptureMovieFileOutput 或 来完成 UIImagePickerController 。 的优点 AVAssetWriter 是它使用硬件编码。

实时识别

iOS 可以识别从视频设备捕获的条形码和人脸。

以下示例演示如何识别 QR 和 EAN13 条形码。 已配置 , AVCaptureSession 并将 T:AFoundation.AVCaptureMetadataOutput 添加到其中。 的 MyMetadataOutputDelegate 子类 AVCaptureMetadataOutputObjectsDelegate 分配给其 P:AVFoundation.AVCaptureMetadataObject.Delegate 属性。

必须将 MetadataObjectTypes 添加到 之后 AVCaptureMetadataOutput 设置数组。

此示例演示 的简单子类,该类 AVCaptureMetadataOutputObjectsDelegate 在识别条形码时引发事件。

session = new AVCaptureSession();
var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
var input = AVCaptureDeviceInput.FromDevice(camera);
session.AddInput(input);
//Add the metadata output channel
metadataOutput = new AVCaptureMetadataOutput();
var metadataDelegate = new MyMetadataOutputDelegate();
metadataOutput.SetDelegate(metadataDelegate, DispatchQueue.MainQueue);
session.AddOutput(metadataOutput);
//Confusing! *After* adding to session, tell output what to recognize...
metadataOutput.MetadataObjectTypes = new NSString[] {
    AVMetadataObject.TypeQRCode,
    AVMetadataObject.TypeEAN13Code
//...etc...
public class MyMetadataOutputDelegate : AVCaptureMetadataOutputObjectsDelegate
    public override void DidOutputMetadataObjects(AVCaptureMetadataOutput captureOutput, AVMetadataObject[] metadataObjects, AVCaptureConnection connection)
        foreach(var m in metadataObjects)
            if(m is AVMetadataMachineReadableCodeObject)
                MetadataFound(this, m as AVMetadataMachineReadableCodeObject);
    public event EventHandler<AVMetadataMachineReadableCodeObject> MetadataFound = delegate {};
 

语音合成

在 iOS 7 及更高版本中,AV Foundation 支持使用针对语言和区域设置本地化的语音进行语音合成。

在最简单的形式中,文本转语音只需两个类即可完成:

var ss = new AVSpeechSynthesizer();
var su = new AVSpeechUtterance("Microphone check. One, two, one two.") {
	Rate = 0.25f
ss.SpeakUtterance(su);          
 

维护 AVSpeechSynthesizer 的内部队列为 AVSpeechUtterance 。 应用程序开发人员无法访问队列,但可以使用 和 StopSpeaking 暂停或停止 PauseSpeaking 合成器。 事件(如 DidStartSpeechUtterance WillSpeakRangeOfSpeechString )是应用程序开发人员修改以前排队的序列的机会。