Сжатие и кодирование AVAsset в mp4

Я пытаюсь сжать AVAsset до более низкого качества, а затем экспортировать его как mp4. Входным активом может быть любой тип видео, который позволяет камера.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь экспортировать актив в AVAssetExportPresetMediumQuality, он терпит неудачу при первом операторе защиты, когда исходный вход представляет собой файл mp4. Однако, если я изменю его на AVAssetExportPresetPassthrough, он будет работать, но не сжимает файл. Есть ли одностороннее решение для сжатия/кодирования ресурса, который изначально может быть .mov или .mp4?

func encodeVideo(asset: AVAsset, completionHandler: @escaping (URL?, String?) -> ())  {
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
        completionHandler(nil, nil)
        return
    }
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
    let filePath = documentsDirectory.appendingPathComponent("compressed-video.mp4")
    if FileManager.default.fileExists(atPath: filePath.path) {
        do {
            try FileManager.default.removeItem(at: filePath)
        } catch {
            completionHandler(nil, nil)
        }
    }
    exportSession.outputURL = filePath
    exportSession.outputFileType = .mp4
    exportSession.shouldOptimizeForNetworkUse = true
    let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
    let range = CMTimeRangeMake(start: start, duration: asset.duration)
    exportSession.timeRange = range

    exportSession.exportAsynchronously {
        switch exportSession.status {
        case .failed:
            print("Conversion Failed")
            completionHandler(nil, exportSession.error?.localizedDescription)
        case .cancelled:
            print("Conversion Cancelled")
            completionHandler(nil, exportSession.error?.localizedDescription)
        case .completed:
            completionHandler(exportSession.outputURL, nil)
            default: break
        }
    }
}

person Nick    schedule 10.05.2020    source источник
comment
Что значит «не прошел первый тест»?   -  person matt    schedule 10.05.2020
comment
Первое охранное заявление   -  person Nick    schedule 10.05.2020
comment
Вы зарегистрировали доступные пресеты для актива?   -  person agibson007    schedule 11.05.2020


Ответы (2)


После некоторого дальнейшего тестирования и исследований это кажется проблемой / возможной ошибкой с симулятором (симулятор Xcode 11.1 и iPhone 11 Pro, iOS 13.1). Не уверен, что это распространяется на другие симуляторы, но приведенный выше код с использованием AVAssetExportPresetMediumQuality работал при тестировании моего устройства.

person Nick    schedule 11.05.2020

Я вижу, вы ответили на свой вопрос, сказав, что проблема в симуляторе. Мой совет — протестировать процессы AVFoundation на устройстве. Симулятор не всегда достаточно оснащен для работы с кейсами. Кроме того, проблемы, которые могут возникнуть на устройстве, могут никогда не проявиться в симуляторе. В любом случае ваш код подходит для преобразования в формат mp4. Удачи!

person Nare Muradyan    schedule 19.05.2020