大多数浏览器和
Developer App 均支持流媒体播放。
-
探索 tvOS 连续互通相机
探索如何在 Apple tvOS 上的 App 中引入 AVFoundation、AVFAudio 和 AudioToolbox ,并为客厅打造相机和麦克风体验。了解如何利用设备发现 API 在现有的 iOS 相机体验中支持 Apple tvOS,构建使用 iPhone 作为网络相机或 FaceTime 通话源的 App,并探讨在开发 Apple tvOS 时的特殊注意事项。我们还将向你展示如何为 Apple tvOS 启用录音,以及如何使用回声消除来创建出色的语音驱动体验。
资源
相关视频
WWDC23
WWDC22
-
下载
大家好 我是 Kevin Tulod Apple tvOS 团队一名软件工程师 我叫 Somesh Ganesh Core Audio 团队的一名工程师
在本讲中 我们将讨论 如何将相机和麦克风支持功能 加入到你的 Apple tvOS App 中
Apple tvOS 17 将连续互通相机 和麦克风加入 Apple TV 现在 你可以流式传输你的 iPhone 或 iPad 中的相机和麦克风数据 将其作为 Apple tvOS 上的输入 这为大屏幕开辟了 全新的 App 类型和体验 Apple tvOS 上的 大多数 App 通常分为两类: 一类是内容播放 App 比如 流式传输的电影和电视节目 另一类就是游戏
连续互通相机使你能为 Apple tvOS 构建全新的 App 比如内容创作 App 用于录制影音 或是像视频会议 和实时流媒体直播等社交 App
你甚至可以将相机和麦克风集成到 现有的流媒体 App 和游戏中 以创建在旧版 Apple tvOS 系统中 不可能实现的全新功能 该功能可以为电视 提供各种各样的 App 我将演示如何将 连续互通相机和麦克风 加入到你的 Apple tvOS App
去年 macOS Ventura 加入了连续互通相机功能 它可以将 iPhone 作为网络相机 你只需 将你的手机靠近你的 Mac 相机和麦克风 就可作为输入设备使用了 如果你还不熟悉 macOS 的 连续互通相机功能 你可以查看 WWDC 2022 中关于此主题的会话讲座
在本讲中 首先我将 大概简述 Apple tvOS 中 目前可用于 访问相机和麦克风的 API 接着 我将深入讲解 App 在 Apple tvOS 如何兼容连续互通相机 使用 iPhone 或 iPad 作为相机和麦克风
我会简要地介绍如何在 Apple tvOS 上 构建出色的 App 体验 重点强调与其他平台开发相比 在 Apple tvOS 上进行开发 有哪些相似点与不同点 最后 Somesh 会向你介绍 你的 App 可以调用的麦克风 API 以满足你的各种复杂音频需求
让我们先来了解一下 采集设备的 API:
AVFoundation AVFAudio 以及 AudioToolbox 让你可以访问相机和麦克风 用以采集影音 让我们回顾一下 App 是如何使用采集设备 特别是使用 AVFoundation 中的 AVCapture 大类
首先 App 使用 AVCaptureDevices 和 AVCaptureDeviceInputs 来代表相机和麦克风 将它们接入到 AVCaptureSession AVCaptureSession 是所有与采集相关的主要对象
AVCaptureOutputs 将输入的数据以各种方式呈现出来 你可以使用这些 来录制影片和抓拍照片 访问相机和麦克风缓冲区 或者从输入设备 采集其他元数据 要在 UI 中显示实时摄像头源 你可使用 AVCaptureVideoPreviewLayer 这是一种特殊的输出类型 它属于 CALayer 的子类 通过 AVCaptureConnections 数据从采集输入 流向兼容的输出设备 从 Apple tvOS 17 开始 你在 iOS、macOS 和 Apple tvOS 上 可以使用这些采集 API
如果你是第一次使用 AVFoundation 采集功能进行开发 可在 developer.apple.com/cn 的 Capture Setup 起始页进一步了解 Apple tvOS 系统现在也支持 iOS 系统上所提供的 相同的相机和麦克风 API 如果你已经为 iOS 系统 构建了相机或麦克风 App 那你的大部分代码 在 Apple tvOS 上将正常工作 但有一些 API 和 编码惯例是不同的
由于 Apple TV 没有内置的影音输入 因此在你使用相机和麦克风之前 你的 App 需要 调用 Device Discovery 功能 这是为了确保你的 App 可以处理边缘情况 如连续互通设备的出现和消失
在 Apple tvOS 上 App 的启动 也有些与 iOS 不同的细微差别 我们将讨论这些注意事项 以获得最佳的 Apple tvOS App 体验
iOS 上相同的相机和麦克风 API 现在也可在 Apple tvOS 上使用 因此 我将向你介绍如何在现有的 iOS App 中添加 Apple tvOS 支持
我已为 iOS 系统构建完成了 一个简单的相机和麦克风 App 该 App 具有基本的 UI 可以访问相机和麦克风 来拍照、录音或录像 通过本讲 我将带你了解 如何使用新的连续互通相机和 Mic API 在你的 App 中添加 Apple tvOS 支持 让我们来看看它是如何构建的
在 Xcode 开发工具中 打开 ContentView 你可在此定义你的 App 的 UI 在此 App 规定了我们在屏幕上 看到的基本 UI 元素的位置 最重要的是 CameraPreview 视图 它连接到一个 AVCaptureVideoPreviewLayer 来显示所有其他 UI 元素后面的实时相机预览
接着是 CaptureSession 类 它封装了 AVFoundation 中的几个 AVCaptureSession 类 此类有一个 AVCaptureSession 属性 用于控制选择哪个采集输入设备 以及输出数据的位置 在本例中 输出是在 ContentView 中显示的 AVCaptureVideoPreviewLayer
CaptureSession 类中还有 一个函数用于设置有效视频输入 在该函数中 App 会验证所选的输入 配置 AVCaptureSession 并启动会话 数据流就会 从 AVCaptureDevice 开始采集 流向并显示在 ContentView 中的预览层
所有这些 AVCapture API 现在也可在 Apple tvOS 上使用 因此 我将在 App 所支持的操作系统中添加 Apple tvOS
我现在正在 项目导航中选择项目 高亮显示 App 目标 并添加 Apple TV 作为支持的目标设备
这样 该 App 就可以在 Apple tvOS 上构建和运行 但是 由于没有可用的输入设备 该 App 实现不了太多功能 从查找采集设备开始 并选择其可在 Apple tvOS 上使用 这将带我们了解连续互通相机
在开始 AVCapture 相关的任何操作之前 你的 App 应确保拥有 使用影音采集设备的权限 这让你的 App 有机会 向用户解释为何需要访问这些设备 用户可以选择接受或拒绝访问 请记得在你的 Info.plist 中 设置相机和麦克风的使用密钥 此描述信息 将在授权验证提示时显示给用户
你可能习惯于 为用户的个人设备构建 App 比如 iPhone 或 iPad 这些设备都自带有内置相机 然而 Apple TV 是 多人通过自己的 iCloud 账户 进行共享的一个公用设备 为了在公用设备上实现最佳体验 任何拥有兼容设备的用户 包括访客 都可将其设备 作为连续互通相机使用
这意味着用户 可以在家里、在朋友家 甚至在度假屋 这样的共享空间 使用你的 App 录音功能 同时也意味着相机 可能随时出现或消失 你的 App 应该能够处理这些情况
AVKit 现在提供了 一个新的视图控制器 名为 AVContinuityDevicePickerViewController 你可以使用这个控制器 选择一个符合条件的连续互通设备 来作为相机和麦克风使用 该视图控制器会列出 所有已登录到 Apple TV 的用户 并允许用户连接其设备 用于连续互通相机功能 还有一种方法 可让访客与 Apple TV 配对 来使用其 iOS 设备 用于连续互通相机功能
访问采集设备时 你的 App 应首先检查 是否有可用的设备 如果有一个设备可用 你可以开始使用采集设备 启动采集会话 并将数据 发送给任一 AVCaptureOutputs 若无可用设备 请使用设备选择器 向用户显示相关的 UI 这将引导用户完成 分享其设备的相机和麦克风的过程 一旦选中某个设备 视图控制器将调用一个委托回调 通知你有一个设备出现了 然后 你可以验证该设备的可用性 并继续启动采集会话 在后台 Apple tvOS 和 iOS 一起工作 来建立这种连接 选定设备后 Apple tvOS 将对靠近 Apple TV 的 符合条件的用户设备 进行 ping 检测 并提示确认 用户随后可以在任何 收到通知的设备上确认接受连接
此时 你即可在你的 App 中使用相机和麦克风 相机和麦克风也可开始流式传输
为了在你的 SwiftUI App 中 显示设备选择器 AVKit 提供了 continuityDevicePicker 修饰符 这是 Apple tvOS 17 的新功能 用于显示选择器 它的显示状态 由一个状态变量来更新 就像其他内容显示的视图修饰符 当设备被选中并变为可用时 该选择器将消失 并用 AVContinuityDevice 调用回调 该对象 对 AVCaptureDevices 进行引用 AVCaptureDevices 与一个给定的物理设备相关联 比如 iPhone 或 iPad
在使用 AVContinuityDevicePickerViewController 的 UIKit App中 也可显示设备选择器 该视图控制器接受一个委托 该委托提供可选的生命周期事件 及一个回调 当 AVContinuityDevice 被选中并可用时 会调用该回调 当这样的设备变为可用时 采集设备 也将被发布到其他设备监听器上 比如 AVCaptureDeviceDiscoverySession 或者 AVCaptureDevice 上的 KVO 监听器 请记住 连续互通相机 是 Apple tvOS 上唯一的采集设备 这意味着你的 App 将必须处理以下情况: 相机和麦克风从不可用到可用 反之亦然
在所有跨平台上 AVCaptureDevice.systemPreferredCamera 允许你访问最合适的相机 该 API 现在 Apple tvOS 上可用 运行方式与其他平台上完全相同
该属性值会依据 相机的可用与否进行更新 Apple TV 一次 只能接入一个连续互通相机 空值表示无可用相机 而非空值则表示 有一个可用的连续互通相机 你可使用键值监听 来监视 systemPreferredCamera 的变化 在 Apple tvOS 上 连接的采集设备类型 是 continuityCamera
当使用键值监听 systemPreferredCamera 属性时 你的 App 可根据相机的可用性 重新评估当前所处状态 当相机可用时 你可启动 AVCaptureSession 来开始录制视频或音频 当相机不可用时 你应该执行必要的卸载操作 取消先前的采集会话 向用户指出该设备已不再可用 并让他们选择连接一个新的设备 一旦连续互通相机 连接到 Apple TV 你的 App 就可以访问 许多现有的相机采集 API 比如 你可以使用 AVCaptureMetadataOutput 获取每帧视频的元数据 如检测到的人脸或身体 你可使用 AVCapturePhotoOutput 采集高分辨率的照片 使用AVCaptureMovieFileOutput 录制包含影音的影片 并监视视频效果或控制相机属性 比如 zoomFactor 通过连续互通相机 API 现在有许多相机 API 可在 Apple tvOS 上使用 你可以参考之前的视频 深入了解高级相机采集功能和技术 以上介绍的是你的 App 需要使用 Apple tvOS 特定的 API 用以 发现和选择连续互通采集设备 让我们将此功能添加到 我们正在开发的 App 中
回到 Xcode 开发工具 在 ContentView 中 已知我们需要一个 Apple tvOS 上的状态变量 来控制设备选择器的显示状态
我将继续添加状态变量 并使用编译保护 确保该变量 仅在 Apple tvOS 上使用
在 ContentView 的底部 我将创建一个仅限 Apple tvOS 使用的扩展 来处理连续互通相机特定逻辑
然后 我将添加一个计算变量 用于创建一个按钮 通过切换我们添加的状态变量 来显示设备选择器
接着 我将添加一个回调处理器 当有连续互通相机接入时 就会调用该回调处理器 一旦连接成功 这将设置相机为有效视频输入 从而启动采集会话
最后 我将添加一个方法 来激活某个连续互通相机 以防万一其已被连接
现在 让我们开始添加 UI
在视图主体中 我将把 设备选择器按钮添加到我的视图中
然后 我将添加 continuityDevicePicker 视图修饰符 并将其连接到 之前添加的状态变量和回调函数
最后 我将添加一个任务 如果连续互通设备已连接 要尝试将其激活
这是在现有 iOS 相机 App 添加 Apple tvOS 支持 所需全部代码改动 现在我们在 Apple TV 上 运行它 看看是什么样子吧
App 启动 显示基本的 UI 但还没有摄像头源 因为我还没有连接相机 我将继续选择我添加的按钮 来打开设备选择器
这为我提供了连接相机的选项 我将继续 选择连接用户 Justin 并按照说明进行配对
连续互通相机就连上了! 这是一个 Apple tvOS 版本的 App 的样子 它使用与 iOS 相同的共享代码 只需进行一些微调 即可在 Apple tvOS 上添加 Device Discovery 相机 API 的 现有用法没有任何改变 我甚至可以继续拍照 就像在 iOS App 中一样
这就是 Apple tvOS 上的 连续互通相机
若你要将现有 App 移植到 Apple tvOS 上 或者刚刚开始 进行 Apple tvOS 开发 我想快速概括一下 各平台的一些细微差别
Apple tvOS 上最显著的区别 是用户交互方式 Apple tvOS 不能直接触摸使用 用户通过焦点引擎与系统进行交互 通过滑动、方向箭头按键以及 其他遥控器上的按钮与系统交互
作为一种公用设备 Apple tvOS 可供多人使用 支持多用户和多访客接入使用 所以 你的 App 可能需要处理个人信息 这点与其它平台不同 最后 Apple tvOS 有独特的文件存储策略 如果你正在编写一个 用于录制影音的内容创作 App 这点尤为重要 让我们更详细地来了解一下
请记住 磁盘空间是共享资源 磁盘空间的主要消耗者包括: 无法删除的操作系统; 框架和 App 二进制文件 其中 一部分可在开启设置的情况下卸载; 大部分磁盘空间用于缓存临时数据 Apple tvOS App 大多是为 内容消费而构建的 比如流式传输 这需要非常大的可用缓存空间 保持这种磁盘空间模式 有助于确保所有 Apple tvOS App 的最佳用户体验
在 iOS 上 你可使用 FileManager 将数据持久存储到 .documentDirectory 路径上 但是 在 Apple tvOS 上 不建议使用此 API
Apple tvOS 操作系统 不允许持久存储大文件 虽然头文件提供了.documentDirectory 但是使用此路径将导致运行错误 因此 为 Apple tvOS 构建 App 时 你的 App 应仅使用 .cachesDirectory 文件夹
此文件夹中的数据 将在你的 App 运行时可用 但在 App 启动过程中 这些数据可能会被从磁盘中清除 因此 最好尽快 将数据转移到其他地方 比如 将数据上传到云端 并在不再需要该数据时 将其从磁盘中删除 Apple tvOS 中 还有其他文件存储选项 其中也一些有趣的多用户用例 比如 你可以使用 CloudKit 将 App 数据存储在 iCloud 甚至可以分用户进行存储 我们介绍过 Apple tvOS 多用户存储选项 非常支持你参考 之前视频以获取更多信息 如果你是 Apple tvOS 开发的新手 请查看 developer.apple.com/cn 上的 “规划你的 Apple tvOS App”页面 该页面介绍了 开发 Apple TV 时 需要考虑的不同功能和注意事项 以上介绍了如何利用 Apple tvOS 17 中 新的连续互通相机 和 Device Discovery API 构建出色的 Apple tvOS App 体验 现在 我们来 介绍一下在 Apple tvOS 17 中 你可以访问的各种麦克风功能 App 将首次能在 Apple tvOS 上 使用麦克风!
让我们立即来了解一下 你需要在 App 中执行哪些操作 来利用此功能 以下是今年所做的 一些内容变动的概述 在 Apple tvOS 的 AVFAudio 框架中增加了 Audio Session
如同在 iOS 上一样 Audio Session 是系统级接口 你可在该接口中告知 你打算在 App 中如何使用音频 比如 你可以注册并处理 诸如中断或路线变更之类的通知 并设置你的 App 的类别和模式
全套录制 API 也已从 iOS 移植到 Apple tvOS
包括 AVFAudio 中的录制 API 以及 AudioToolbox 框架 让我们从 Audio Session 开始
在 Apple tvOS 17 中 App 将能够在 Apple TV 上 使用几种不同的麦克风设备 这可能是一个连续互通麦克风 比如 iPhone 或 iPad 或者像 AirPods、或其他可以直接 与 Apple tvOS 设备配对的蓝牙设备
你可以通过 AVAudioSessionPort 类型 来识别输入设备的类型
完成 Device Discovery 流程后 你将有权 访问 AVContinuityDevice 它有一个 audioSessionPorts 属性
可从该属性中 查询有关音频设备的信息 包括其端口类型
现在有一个新的端口类型 用于连续互通麦克风 如果你想基于输入设备的类型 在你的 App 中执行任何特定操作 则建议使用此端口作为标识符
此流程仅适用于 被归类为 AVContinuityDevice 的 iPhone 和 iPad
你也可以继续使用 现有的 Audio Session API 来查询系统中可用的输入
AirPods 或蓝牙麦克风的 现有端口类型 也已从 iOS 移植过来 在采集设备可用这一基础上 现在我们来谈谈 麦克风设备的可用性 以及在 Apple tvOS 上你该如何监控它 Apple TV 没有内置的麦克风 你的 App 也无法保证 始终可以访问麦克风设备 为此 Audio Session 中的 InputAvailable 属性 现在支持键值监听 你可通过该属性来监听 何时会有或者没有可用麦克风设备
强烈建议你监听此属性 来查看麦克风可用性的动态变化 这也有助于你确定何时激活 你的 Audio Session 并开始 I/O 过程 同时 当麦克风设备 在系统中出现或消失时 处理你的 App 的状态
接着 与 iOS 相类似 现在在 Apple tvOS 17上 也可使用录制权限 API 你可以检查用户是否已授予 你的 App 访问麦克风的权限 如果没有 则需要请求录制权限
为了避免在开始 I/O 过程中 出现失败的情况 建议 App 确保拥有录制权限
最后同样重要的是 在 Audio Session 中 支持输入的类别和模式 比如:playAndRecord 类别、 语音聊天和视频聊天等模式 也在 Apple tvOS 上可用 你可以参考我们的头文件 AVAudioSessionTypes 来帮助你确定哪种音频会话 类别和模式最适合你的 App 以上是 Apple tvOS 17 中新增的 所有音频会话的相关变动 现在 让我们来谈谈 种类繁多的录制 API 及其推荐用例
首先是 AVAudioRecorder
这是将音频 录制为音频文件的最简单方法 如果你只需要针对 非实时用例 记录麦克风中 接收到的任何内容 则 AVAudioRecorder 是你的首选 它可以设置各种编码格式、 特定的文件格式和采样率等等
接着 我们还有 AVCapture 正如 Kevin 之前提到的 如果相机和麦克风同时在运行 你可以利用现有的 iOS AVCapture API 来获得麦克风的访问权限 以便完成最基本的录制 再接着是 AVAudioEngine
AVAudioEngine 同时支持 简单和复杂音频的录制和播放处理 一个例子是卡拉 OK App 在此 App 中 你可以 分析来自用户麦克风的声音输入 并将此麦克风输入 与你播放的音轨相混合
现在 有些 App 可能希望直接与 实时音频 I/O 周期进行交互 AVAudioEngine 也提供了实时接口
App 可通过 AVAudioSinkNode 和 AVAudioSourceNode 提供实时安全渲染回调
你还可以通过 AVAudioEngine 获取语音处理功能权限 对于处理底层接口界面的 App 相应的 iOS 机制 也已移植到了 Apple tvOS 上
对于非实时录制用例 你可使用 AudioQueue 为了直接与 实时音频 I/O 周期进行交互 你可使用现有的 AudioUnit API 中的音频单元 AU RemoteIO 和 AU VoiceIO
如果你想获取有关 这些 API 的更多详细信息 建议你查看 AVFAudio 和 Audio Toolbox 框架的 开发者网站来寻求帮助
现在 若你需要一个麦克风音频流 在此音频流中 Apple TV 的播放需要消除回声 比如 以会议用例为例 强烈建议 选择我们的语音处理 API 我来解释一下原因 与标准的回声消除问题相比 比方说在 iPhone 上消除回声 录音和播放发生在同一设备上 这是 Apple tvOS 设置中的所有新功能 在启用了连续互通麦克风的线路上 录音是在 iPhone 或 iPad 上进行的 但是播放却是流式传输到 Apple tvOS 设备上播放 可通过 任意一套电视扬声器播放声音 比如家庭影院设置、电视音响 甚至一对立体声的 HomePods 这些扬声器设备大多都能 播放各种格式的声音 比如:5.1 和 7.1 LPCM 并进行自己风格的音频处理 以提高用户体验 除此之外 在一般的 Apple TV 设置中 用户可能与麦克风设备相距几英尺 而该麦克风设备可能 更接近那些大声播放设备
所有这些情况衍生出了一个 非常具有挑战性的回声控制问题 在这种情况下 我们希望取消 所有来自 Apple TV 的播放 同时 高质量地采集 来自局部环境的音频 为了帮助你克服所有这些挑战 Apple tvOS 17 现已加入 新的语音处理和回声消除技术 你可以简单地利用 现有的 iOS API 来实现 也可以在 Apple tvOS 上使用 你只需要 在 AVAudioEngine 中 调用 inputNode 中的 setVoiceProcessingEnabled 即可 你还可使用 VoiceProcessingIO 子类型的 AU VoiceIO 音频单元 来访问此功能 有关我们的语音处理 API 及其提供功能的更多详细信息 请参阅我们的讲座 “语音处理中的新内容”一讲 以上就是今年 Apple tvOS 17 所有全新的音频 API
现在 让我们回到我们的 App 看看如何利用其中一些麦克风功能
回到 Xcode 开发工具 打开我的 AudioCapturer 类
该类抽象了底层音频 API 的 所有细微差别 使其与 App 代码分离
该类有自己的 AVAudioEngine 实例 这是我在本例中 要使用的录制 API
该类中还有自己的 共享 Audio Session 实例
让我们快速了解一下 该类都做了哪些事 在应用层面 它在激活前设置了音频会话的 类别和模式 使用正确的格式 设置底层 AVAudioEngine⋯⋯
并在输入节点上设置语音处理 具有用户可控的 切换开关 可以绕过它
在本例中 我在非实时背景下运行底层引擎 现在 让我们看看需要如何修改这个 App 以适用于 Apple tvOS 假设一个麦克风设备始终可用 iOS App 的构建和 Apple tvOS 是一样的 我需要添加一个监听器 以监听 inputAvailable KVO 通知 确保在启动我的 Audio Session 并随之启动 I/O 过程之前 我有可用的输入麦克风设备 我将继续在这里添加它
当麦克风设备 在系统中出现或消失时 我还需要 确保处理 App 的状态 这个问题的发生 可能仅仅是因为用户在会话期间 断开其手机与 Apple TV 连接
现在这 App 应该在 Apple TV 运行良好 让我们看看它的表现!
我的 App 现在处于音频模式 我可以按播放按钮播放歌曲 然后同时录下自己的讲话
哇 这首歌真是太赞了! 每次听到它 我总是感觉想跳舞
这太有趣了! 现在 在我们 一直在进行的语音处理模式中 从 Apple TV 播放的这首歌曲将被取消 只留下来自局部环境的音频 被发送到 App 中
哇 这首歌真是太赞了! 每次听到它 我总是感觉想跳舞
以上是 Apple tvOS 的回声消除功能
本讲内容到此结束! 让我们回顾一下我们所学习的内容
首先我们从应用层面介绍这一功能 并谈到了其在 Apple tvOS 上 解锁的新类型的 App 然后 我们讨论了 新的 Device Discovery API 用于显示设备选择器 并选择一个连续互通设备 我们回顾了现在能在 Apple tvOS 使用的 相机和麦克风 API 最后 我们重构了 现有的相机和麦克风 App 以适应新的 Apple tvOS 尽可能地共享原有代码 仅仅只是添加了 Device Discovery 我们还回顾了一些 Apple tvOS 特有的注意事项 我们非常高兴看到 你将相机和麦克风支持功能 加入到你的 Apple tvOS App 中 我们迫不及待地 想要看到你使用这些功能 在此平台上开发你的 App! 谢谢
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。