es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , , ,

Answer

  1. Avatar for 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.

Comments are closed.