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

如何将视频PHAsset导出为包含GPS元数据的NSData?

保留视频PHAsset位置元数据的解决方案

你遇到的问题核心在于:直接复制AVURLAsset的临时文件或使用AVAssetExportSession时未正确处理元数据传递,导致GPS信息丢失。以下是两种可靠的解决方法:

方法一:使用PHAssetResourceManager直接导出原始数据(推荐)

PHAssetResourceManager可以直接获取PHAsset的原始媒体数据,完整保留所有元数据(包括GPS信息),无需经过AVAsset的转换,是最稳妥的方式。

代码示例:

// 获取PHAsset对应的原始资源
PHAssetResource *resource = [[PHAssetResource assetResourcesForAsset:asset] firstObject];
NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:resource.originalFilename]];

// 导出原始数据到临时文件
[[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource
                                                              toFile:tempFileURL
                                                          options:nil
                                                completionHandler:^(NSError * _Nullable error) {
    if (!error) {
        // 读取文件为NSData用于上传
        NSData *videoData = [NSData dataWithContentsOfURL:tempFileURL];
        // 此处执行上传逻辑
    } else {
        // 处理导出错误
    }
}];

方法二:修复AVAssetExportSession的元数据传递

如果必须使用AVAssetExportSession,需要确保正确提取并传递完整的元数据,尤其是GPS相关的元数据项。注意AVAsset的metadata可能不包含全部原始元数据,建议直接从PHAsset获取完整元数据集:

步骤1:从PHAsset提取完整元数据

[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
    if (contentEditingInput) {
        AVURLAsset *urlAsset = (AVURLAsset *)contentEditingInput.audiovisualAsset;
        // 筛选出GPS相关的元数据项
        NSArray *gpsMetadata = [urlAsset.metadata filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
            AVMetadataItem *item = (AVMetadataItem *)evaluatedObject;
            return [item.commonKey isEqualToString:AVMetadataCommonKeyLocation];
        }]];
        // 合并通用元数据与GPS元数据
        NSMutableArray *finalMetadata = [NSMutableArray arrayWithArray:urlAsset.commonMetadata];
        [finalMetadata addObjectsFromArray:gpsMetadata];
        
        // 执行导出逻辑
        [self exportAssetWithMetadata:finalMetadata asset:urlAsset outputURL:yourTempOutputURL];
    }
}];

步骤2:正确配置AVAssetExportSession

- (void)exportAssetWithMetadata:(NSArray *)metadata asset:(AVAsset *)asset outputURL:(NSURL *)outputURL {
    // 使用Passthrough预设避免重新编码,减少元数据丢失风险
    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
    exporter.outputURL = outputURL;
    exporter.outputFileType = AVFileTypeQuickTimeMovie;
    // 设置完整元数据
    exporter.metadata = metadata;
    // 禁止网络优化,防止系统精简元数据
    exporter.shouldOptimizeForNetworkUse = NO;
    
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        if (exporter.status == AVAssetExportSessionStatusCompleted) {
            NSData *videoData = [NSData dataWithContentsOfURL:outputURL];
            // 此处执行上传逻辑
        } else {
            // 处理导出错误
        }
    }];
}

关键注意点:

  • 使用AVAssetExportPresetPassthrough替代AVAssetExportPresetHighestQuality,避免视频重新编码导致元数据丢失;
  • 设置shouldOptimizeForNetworkUse = NO,防止系统为网络传输自动精简元数据;
  • 确保元数据项的格式与输出文件类型匹配(MOV格式需使用QuickTime规范的元数据键)。

内容的提问来源于stack exchange,提问作者haplo1384

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:05:31