Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAssetExportSession stuck (not starting) export

I have attempted to export videos from Photo Library, but the export callback is never executed. I periodically check the progress of the export, and the progress is always zero.

The code below works in 99.9% cases, but sometimes on some devices (absolutely randomly) it stops working and only restart of the iPhone helps.

AVAssetExportSession.Status always in waiting state


class FilesInteractor {
    static func tempDirectoryPath() -> String {
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
        return documentsPath.appendingPathComponent("temp") as String
    }

    static func createTempDirectory() {
        if !FileManager.default.fileExists(atPath: tempDirectoryPath()) {
            try? FileManager.default.createDirectory(atPath: tempDirectoryPath(), withIntermediateDirectories: true, attributes: nil)
        }
    }

    static func testVideoURL(name: String, ext: String = "mov") -> URL {
        createTempDirectory()
        let outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("test").appendingPathComponent("\(name).\(ext)", isDirectory: false)

        log.debug("Test video URL: \(outputURL)")

        return outputURL
    }
}

import AVFoundation

let asset = AVAsset()
let outputURL = FilesInteractor.testVideoURL("output")

let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset1280x720)
exportSession?.outputFileType = .mov
exportSession?.outputURL = outputURL

try? FileManager.default.removeItem(at: outputURL)
exportSession?.exportAsynchronously(completionHandler: {
    print("sometimes never calls")
})

Other video apps also freeze (Filto, Videoleap):

Filto

Videoleap

like image 735
Vasilii Kasnitski Avatar asked Nov 18 '19 10:11

Vasilii Kasnitski


1 Answers

I saw this issue a couple of times on some Github projects and usually it had something to do with how the URL was created. Not sure if the code you put in your question was just some placeholder but I think you should create a fileURL like this instead of "string".

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

Perhaps this will fix it?

like image 147
Bob de Graaf Avatar answered Nov 15 '22 05:11

Bob de Graaf