Files
suixinkan_ios_new/suixinkan/Core/CameraTethering/CameraTethering.md
汉秋 90d135b5ac 完善 OTG 相机有线传图:支持 Sony/Canon 自动识别,页面 detach 保持会话以便再次进入复连。
引入进程级 CameraTetheringSession 与共享 USB Browser;离开传图页仅取消 UI 回调,App 终止时再完整 shutdown 释放 PTP 与 Browser 资源。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 15:45:35 +08:00

3.2 KiB
Raw Blame History

CameraTethering

职责

提供 USB OTG 相机有线连接与 Sony/Canon PTP 边拍边传能力,不包含业务 API 或 OSS 上传。

核心组件

组件 说明
CameraServiceProtocol 相机服务抽象,上层只依赖此协议
CameraTetheringSession 进程级单例,持有共享 AutoDetectCameraService
AutoDetectCameraService 按 USB Vendor ID 自动识别品牌并委托
SonyCameraService Sony 相机实现,封装 SDIO/PTP 下载
CanonCameraService Canon EOS 相机实现,封装 GetEvent/PTP 下载
ImageCaptureDeviceManager Sony ICC 设备管理
CanonImageCaptureDeviceManager Canon ICC 设备管理
PTPHelper 共享 PTP 编解码与命令发送
CameraDownloadStorage 本地下载作用域、目录与文件名消毒

品牌识别

插入 USB 相机后,AutoDetectCameraService 读取 ICCameraDevice.usbVendorID

  • 0x054C → Sony
  • 0x04A9 → Canon
  • 其他 → 提示不支持的相机品牌

业务流程

  1. AutoDetectCameraService.connect() 启动 USB 设备搜索(或复用已有连接)。
  2. 发现相机并完成系统授权后,按 Vendor ID 创建品牌 Service 并 attach。
  3. 品牌 Service 打开 ICC 会话并执行品牌专有 PTP 握手Sony SDIO / Canon SetRemoteMode
  4. 拍摄事件触发 PTP 下载或 catalog 回退,底层先写入临时目录。
  5. 通过 onNewAsset 回调通知上层有新照片。

相机端前置条件

  • Sony设为电脑遥控PC Remote模式
  • Canon:设为电脑遥控 / PC Remote / 照片传输PTP模式
  • 均需关闭「仅充电」模式

依赖

  • ImageCaptureCore系统框架
  • 无第三方库依赖

页面生命周期与资源释放

OTG 相机连接由 CameraTetheringSession.sharedService 进程级持有;CameraServiceFactory.makeAutoDetect() 始终返回该单例。

进入 OTG 页:

  1. .task 调用 WiredCameraTransferViewModel.start()
  2. pipeline.attachToUI(...) 绑定 UI 回调。
  3. connect() 启动或复用 USB 搜索;若已连接则跳过 attach同步状态并补发 detach 期间缓冲的新片。
  4. 发现相机后按 Vendor ID attach 品牌服务,打开 ICC 会话并执行 PTP 握手。

离开 OTG 页detach

  1. .task 取消或 onDisappear 触发 detachFromUI()(幂等)。
  2. 仅清空 onNewAsset / onConnectionStateChange 等 UI 回调,取消 Pipeline 上传/通知任务。
  3. PTP CloseSession、 stop Browser、 nil activeService
  4. 底层 D215 轮询与 PTP 下载可继续,新片写入 pendingAssetsWhileDetached,再次进入时 flush。

App 即将终止shutdown

  1. AppDelegate.applicationWillTerminate 调用 CameraTetheringSession.shutdown()
  2. 品牌 Service 完整断开Sony 先 Position_Key_Setting=Local 再 PTP CloseSession
  3. usbBrowser.stop() 停止 USB Browser 并释放授权状态。

进入后台主动 shutdown系统挂起 USB 时由 deviceBrowserDidResumeOperations 处理恢复。

若返回后再进入无法连接,优先检查日志中是否出现「会话关闭超时」或在非 terminate 场景误调用了 shutdown()