gpt4 book ai didi

swift - 通过 AVAssetExportSession 导出 mp4 失败

转载 作者:搜寻专家 更新时间:2023-10-30 22:23:44 25 4
gpt4 key购买 nike

我开始说我花了很多时间搜索文档、此处和其他地方的帖子,但我无法找到解决此问题的方法。

我正在使用 AVAssetExportSession 导出存储在 AVAsset 实例中的 .mp4 文件。我所做的是:

  • 我检查 AVAssetisExportable 属性
  • 然后我得到一个与 AVAsset 实例兼容的 exportPresets 数组
  • 我采用 AVAssetExportPreset1920x1080,或者,如果不存在,我尝试使用 AVAssetExportPresetPassthrough 导出媒体(仅供引用,100% 的时候,我需要的预设总是包含在列表中,但我也尝试了 passthrough 选项,但无论如何它都不起作用)

outputFileTypeAVFileTypeMPEG4 我也尝试过为文件分配 .mp4 扩展名,但没有任何效果。我总是收到这个错误

Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped" UserInfo={NSUnderlyingError=0x600000658c30 {Error Domain=NSOSStatusErrorDomain Code=-12109 "(null)"}, NSLocalizedFailureReason=The operation is not supported for this media., NSLocalizedDescription=Operation Stopped}

下面是我使用的代码

func _getDataFor(_ item: AVPlayerItem, completion: @escaping (Data?) -> ()) {
guard item.asset.isExportable else {
completion(nil)
return
}

let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: item.asset)
var preset: String = AVAssetExportPresetPassthrough
if compatiblePresets.contains(AVAssetExportPreset1920x1080) { preset = AVAssetExportPreset1920x1080 }

guard
let exportSession = AVAssetExportSession(asset: item.asset, presetName: preset),
exportSession.supportedFileTypes.contains(AVFileTypeMPEG4) else {
completion(nil)
return
}

var tempFileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
tempFileUrl = URL(fileURLWithPath: tempFileUrl.path)

exportSession.outputURL = tempFileUrl
exportSession.outputFileType = AVFileTypeMPEG4
let startTime = CMTimeMake(0, 1)
let timeRange = CMTimeRangeMake(startTime, item.duration)
exportSession.timeRange = timeRange

exportSession.exportAsynchronously {
print("\(exportSession.error)")
let data = try? Data(contentsOf: tempFileUrl)
_ = try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}

最佳答案

似乎在 AVMutableComposition 中转换 AVAsset 实例就成功了。如果有人知道此方法有效的原因,请告诉我。

这是新的_getDataFor(_:completion:)方法实现

func _getDataFor(_ item: AVPlayerItem, completion: @escaping (Data?) -> ()) {
guard item.asset.isExportable else {
completion(nil)
return
}

let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))

let sourceVideoTrack = item.asset.tracks(withMediaType: AVMediaTypeVideo).first!
let sourceAudioTrack = item.asset.tracks(withMediaType: AVMediaTypeAudio).first!
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceVideoTrack, at: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceAudioTrack, at: kCMTimeZero)
} catch(_) {
completion(nil)
return
}

let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: composition)
var preset: String = AVAssetExportPresetPassthrough
if compatiblePresets.contains(AVAssetExportPreset1920x1080) { preset = AVAssetExportPreset1920x1080 }

guard
let exportSession = AVAssetExportSession(asset: composition, presetName: preset),
exportSession.supportedFileTypes.contains(AVFileTypeMPEG4) else {
completion(nil)
return
}

var tempFileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
tempFileUrl = URL(fileURLWithPath: tempFileUrl.path)

exportSession.outputURL = tempFileUrl
exportSession.outputFileType = AVFileTypeMPEG4
let startTime = CMTimeMake(0, 1)
let timeRange = CMTimeRangeMake(startTime, item.duration)
exportSession.timeRange = timeRange

exportSession.exportAsynchronously {
print("\(tempFileUrl)")
print("\(exportSession.error)")
let data = try? Data(contentsOf: tempFileUrl)
_ = try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}

关于swift - 通过 AVAssetExportSession 导出 mp4 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41544359/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com