将 otg_swift OTG 引擎迁入 Core/CameraOTG,并接入旅拍有线传图与历史导入。

恢复 USB 相机连接、边拍边传、三品牌驱动与 SwiftUI 历史导入页,通过适配层对接现有本地上传与 OSS 管道。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 11:22:07 +08:00
parent d7fec35715
commit be9c844bd3
50 changed files with 5721 additions and 20 deletions

View File

@ -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
)
}
}