You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:03:13