Recortar video siempre falla al usar AVAssetExportPresetPassthrough.
Mi código de recorte de vídeo:
func trim(createNew: Bool, with name: String?, file: File, startTime: Double, endTime: Double, completion: @escaping ResultCompletion<file>) {
guard checkFreeSpace(with: file) else {
return handleFailure(error: .fullStorage, completion: completion)
}
guard let originUrl = file.localUrl(),
let originName = file.name.components(separatedBy: ".").first,
let originExtension = file.name.components(separatedBy: ".").last else {
return handleFailure(error: .mediaSavingError, completion: completion)
}
let asset = AVAsset(url: originUrl)
let timeZoneOffset = TimeInterval(TimeZone.current.secondsFromGMT())
let newDate = Date().addingTimeInterval(timeZoneOffset)
let temporaryFileId = "\(file.device ?? "Unknown")-\(newDate.milliseconds)-0-\(originName)_trim.\(originExtension)"
let outputUrl = file.buildLocalUrl(id: temporaryFileId)
AVAssetExportSession.determineCompatibility(
ofExportPreset: AVAssetExportPresetPassthrough,
with: asset,
outputFileType: .mp4) { isCompatible in
print("Can Trim MP4: ", isCompatible)
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
return handleFailure(error: .mediaSavingError, completion: completion)
}
exportSession.outputURL = outputUrl
exportSession.outputFileType = .mp4
let timeRange = CMTimeRange(start: CMTime(seconds: startTime, preferredTimescale: 900),
end: CMTime(seconds: endTime, preferredTimescale: 900))
exportSession.timeRange = timeRange
exportSession.exportAsynchronously { [weak self] in
guard let self = self else {
return
}
exportProgressTimer.invalidate()
switch exportSession.status {
case .completed:
completion(.success(file))
case .failed:
self.handleFailure(error: .mediaSavingError, completion: completion)
case .cancelled:
completion(.failure(FileError.mediaExportCanceled))
default:
break
}
}
}
determineCompatibility
devuelve verdadero
Cuando uso otro preset como el que se encuentra en AVAssetExportSession.exportPresets(compatibleWith: item.asset)
, todo funciona genial
Quizás alguien pueda explicar qué sale mal y cómo puedo solucionarlo. Necesito la misma resolución que en el vídeo original.
¿O cómo puedo convertir con AVAssetWriter
y AVAssetReader
?
davy.ai
El problema parece estar en el preset utilizado para exportar el vídeo recortado. El código actual utiliza AVAssetExportPresetPassthrough, que puede no ser compatible con el asset de entrada en algunos casos.
Una solución sería probar otros presets que sean compatibles con el asset de entrada, verificando AVAssetExportSession.exportPresets(compatibleWith: asset). Otra solución podría ser usar AVAssetWriter y AVAssetReader para recortar y exportar el vídeo. Esto requeriría más código y configuración, pero proporcionaría más control sobre el formato y calidad de salida. También es posible que la resolución del vídeo de salida deba ajustarse para que coincida con la del vídeo original, lo que se podría hacer a través de configuraciones en la sesión de exportación o usando AVAssetWriter/AVAssetReader.