将 otg_swift OTG 引擎迁入 Core/CameraOTG,并接入旅拍有线传图与历史导入。
恢复 USB 相机连接、边拍边传、三品牌驱动与 SwiftUI 历史导入页,通过适配层对接现有本地上传与 OSS 管道。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -0,0 +1,96 @@
|
||||
import Foundation
|
||||
|
||||
/// 旅拍相册 OTG 照片落盘实现:写入 scoped 本地目录并通知传输管道。
|
||||
@MainActor
|
||||
final class TravelAlbumOTGPhotoSink: OTGPhotoSink {
|
||||
private let albumId: Int
|
||||
private let accountKey: String
|
||||
private let pipeline: WiredCameraTransferPipeline
|
||||
private let existingObjectIDsProvider: () async -> Set<String>
|
||||
private let autoUploadProvider: () -> Bool
|
||||
|
||||
/// 初始化旅拍相册 OTG 落盘实现。
|
||||
init(
|
||||
albumId: Int,
|
||||
accountKey: String,
|
||||
pipeline: WiredCameraTransferPipeline,
|
||||
existingObjectIDsProvider: @escaping () async -> Set<String>,
|
||||
autoUploadProvider: @escaping () -> Bool
|
||||
) {
|
||||
self.albumId = albumId
|
||||
self.accountKey = accountKey
|
||||
self.pipeline = pipeline
|
||||
self.existingObjectIDsProvider = existingObjectIDsProvider
|
||||
self.autoUploadProvider = autoUploadProvider
|
||||
}
|
||||
|
||||
/// 保存边拍边传图像数据。
|
||||
func saveLiveShot(
|
||||
data: Data,
|
||||
filename: String,
|
||||
capturedAt: Date,
|
||||
cameraObjectID: String
|
||||
) async throws -> SavedOTGPhoto {
|
||||
let fileURL = try OTGPhotoFileWriter.writeImage(
|
||||
data,
|
||||
filename: filename,
|
||||
accountKey: accountKey,
|
||||
albumID: albumId
|
||||
)
|
||||
return ingestSavedFile(
|
||||
fileURL: fileURL,
|
||||
filename: filename,
|
||||
capturedAt: capturedAt,
|
||||
cameraObjectID: cameraObjectID
|
||||
)
|
||||
}
|
||||
|
||||
/// 保存历史导入已下载文件。
|
||||
func saveDownloadedFile(
|
||||
at url: URL,
|
||||
filename: String,
|
||||
capturedAt: Date,
|
||||
cameraObjectID: String
|
||||
) async throws -> SavedOTGPhoto {
|
||||
let fileURL = try OTGPhotoFileWriter.moveDownloadedFile(
|
||||
from: url,
|
||||
filename: filename,
|
||||
accountKey: accountKey,
|
||||
albumID: albumId
|
||||
)
|
||||
return ingestSavedFile(
|
||||
fileURL: fileURL,
|
||||
filename: filename,
|
||||
capturedAt: capturedAt,
|
||||
cameraObjectID: cameraObjectID
|
||||
)
|
||||
}
|
||||
|
||||
/// 返回当前相册已导入的相机对象 ID。
|
||||
func existingCameraObjectIDs() async -> Set<String> {
|
||||
await existingObjectIDsProvider()
|
||||
}
|
||||
|
||||
private func ingestSavedFile(
|
||||
fileURL: URL,
|
||||
filename: String,
|
||||
capturedAt: Date,
|
||||
cameraObjectID: String
|
||||
) -> SavedOTGPhoto {
|
||||
let relativePath = OTGPhotoFileWriter.relativePath(for: fileURL)
|
||||
let autoUpload = autoUploadProvider()
|
||||
pipeline.ingestDownloadedAsset(
|
||||
assetID: cameraObjectID,
|
||||
filename: filename,
|
||||
localPath: relativePath,
|
||||
capturedAt: capturedAt,
|
||||
autoUpload: autoUpload
|
||||
)
|
||||
return SavedOTGPhoto(
|
||||
assetID: cameraObjectID,
|
||||
relativeLocalPath: relativePath,
|
||||
filename: filename,
|
||||
capturedAt: capturedAt
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user