如何通过AVFoundation获取视频录制时的本地时间及时区?
问题:获取视频录制时的本地时间及时区(不依赖程序运行时区转换)
我需要读取视频元数据,获取视频录制时的当地创建时间及所在时区。当前实现的代码只能拿到UTC时间:
// Create an AVAsset for the video file let asset = AVURLAsset(url: fileURL) print("Loaded AVURLAsset \(String(describing: asset))") if let creationDate = try await asset.load(.creationDate) { if let dateValue = try await creationDate.load(.dateValue) { print("Creation date from metadata: \(dateValue)") } else { print("No parsable creation date from metadata") } } else { print("No creation date from metadata") }
输出结果对比:
Creation date from metadata: 2025-02-23 19:14:20 +0000
Creation date for file: 2025-02-23 11:14:28 -0800
我需要的是视频本身录制时的特定本地时间及时区,而非基于程序运行电脑时区转换UTC时间的结果。
解决方案
AVAsset的.creationDate仅返回UTC时间,要获取录制时区,需要读取视频中存储的额外元数据(取决于录制设备是否写入该信息)。以下是具体实现:
1. 扩展AVAsset获取录制时区
通过筛选视频元数据中的时区相关字段(如EXIF的时间偏移、QuickTime的时区数据)来提取录制时区:
import AVFoundation import ImageIO extension AVAsset { func getRecordingTimeZone() async throws -> TimeZone? { let metadata = try await self.load(.metadata) // 查找EXIF原始时间偏移(适用于MP4等格式) let exifOffsetKey = kCGImagePropertyExifOffsetTimeOriginal as String for item in metadata { if item.commonKey?.rawValue == exifOffsetKey, let offsetString = item.value as? String { return TimeZone(identifier: "GMT\(offsetString)") } } // 查找QuickTime时区元数据(适用于MOV等格式) let quickTimeTimeZoneKey = kQuickTimeMetadataKeyCreationTimeZone as String for item in metadata { if item.key?.rawValue == quickTimeTimeZoneKey, let timeZoneData = item.value as? Data { do { return try JSONDecoder().decode(TimeZone.self, from: timeZoneData) } catch { print("解析QuickTime时区失败: \(error)") } } } return nil } }
2. 主逻辑整合
将UTC时间与录制时区结合,得到录制时的本地时间:
let asset = AVURLAsset(url: fileURL) print("Loaded AVURLAsset \(String(describing: asset))") if let creationDate = try await asset.load(.creationDate), let utcDate = try await creationDate.load(.dateValue) { print("UTC创建时间: \(utcDate)") if let recordingTimeZone = try await asset.getRecordingTimeZone() { // 格式化得到录制时的本地时间 let dateFormatter = DateFormatter() dateFormatter.timeZone = recordingTimeZone dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ" let localRecordingTime = dateFormatter.string(from: utcDate) print("录制时本地时间: \(localRecordingTime)") print("录制时区: \(recordingTimeZone.identifier)") } else { print("未找到视频录制时区元数据") } } else { print("未找到视频创建时间元数据") }
注意事项
- 并非所有视频都包含时区元数据,这由录制设备的设置决定(部分设备可能只写入UTC时间,不存储时区信息)
- 不同视频格式(MOV/MP4等)的时区存储字段可能不同,需根据实际情况适配元数据键
- 若无法获取时区元数据,只能退而求其次使用UTC时间
内容的提问来源于stack exchange,提问作者Villahousut
相关产品推荐
相关产品推荐

