Skip to content

App crashes in release mode #19

@Asherbinyy

Description

@Asherbinyy

The download works fine in the debug mode but, crashes when I run the app in the release.
PS: I'm using the latest version.
This is the code I use from package:

`import Foundation
import Photos
import YoutubeDL
import PythonKit

@objc(YoutubeDLWrapper)
class YoutubeDLWrapper: NSObject {

func downloadVideo(url: String, completion: @escaping (Result<String, Error>) -> Void) {
    
    if let url = URL(string: url) {
        let documentsDirectory: URL
                if #available(iOS 16.0, *) {
                    documentsDirectory = URL.documentsDirectory
                } else {
                    documentsDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
                }
                FileManager.default.changeCurrentDirectoryPath(documentsDirectory.path)
        Task {
            do {
                let path = try await self.startDownload(url: url)
                completion(.success(path))
            } catch {
                completion(.failure(error))
            }
        }
    } else {
        completion(.failure(NSError(domain: "Invalid URL", code: 400, userInfo: nil)))
    }
}

private func startDownload(url: URL) async throws -> String {
    print(#function, url)
    clearCache()
    do {
        let (info, _, _) = try await download(url: url)
        guard let path = info.flatMap({ String($0["_filename"]) }) else {
            print(#function, "no '_filename'?", info ?? "nil")
            throw NSError(domain: "Download Error", code: 500, userInfo: [NSLocalizedDescriptionKey: "Failed to get the output file path"])
        }
        let outputURL: URL
        if #available(iOS 16.0, *) {
            outputURL = URL(filePath: path)
        } else {
            outputURL = URL(fileURLWithPath: path)
        }
        print("############## finished #############")
        print("outputURL:\(outputURL)")
        export(url: outputURL)
        notify(body: "Finished")
        return outputURL.path
    } catch {
        print(#function, error)
        throw error
    }
}

private func export(url: URL) {
    PHPhotoLibrary.shared().performChanges({
        _ = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
    }) { success, error in
        print(#function, success, error ?? "")
        DispatchQueue.main.async {
            print("error:\(String(describing: error))")
        }
    }
}

private func download(url: URL) async throws -> (PythonObject?, [String], [PythonObject]) {
    let str = NSLocalizedString("Extracting info", comment: "progress description")
    print("str:\(str)")
    var info: PythonObject?
    var files = [String]()
    var formats = [PythonObject]()
    var error: String?
    let argv: [String] = (
        url.pathExtension == "mp4"
        ? ["-o", url.lastPathComponent]
        : [
            "-f", "bestvideo+bestaudio[ext=m4a]/best",
            "--merge-output-format", "mp4",
            "--postprocessor-args", "Merger+ffmpeg:-c:v h264",
            "-o", "%(title).200B.%(ext)s",
        ]
    ) + [
        "--no-check-certificates",
        url.absoluteString,
    ]
    print(#function, argv)
    try await yt_dlp(argv: argv) { dict in
        info = dict["info_dict"]
        let status = String(dict["status"]!)
        switch status {
        case "downloading":
            print("downloading")
        case "finished":
            print(#function, dict["filename"] ?? "no filename")
            files.append(String(dict["filename"]!)!)
            formats.append(info!)
        default:
            print(#function, dict)
        }
    } log: { level, message in
        print(#function, level, message)
        if level == "error" || message.hasSuffix("has already been downloaded") {
            error = message
        }
    } makeTranscodeProgressBlock: {
        let t0 = ProcessInfo.processInfo.systemUptime
        return { (progress: Double) in
            print(#function, "transcode:", progress)
            let elapsed = ProcessInfo.processInfo.systemUptime - t0
            let speed = progress / elapsed
            let ETA = (1 - progress) / speed
            guard ETA.isFinite else { return }
            print("progress:\(Int64(progress * 100))")
        }
    }
    if let error {
        throw NSError(domain: "App", code: 1, userInfo: [NSLocalizedDescriptionKey: error])
    }
    return (info, files, formats)
}

private func clearCache() {
    let fileManager = FileManager.default
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    do {
        let fileName = try fileManager.contentsOfDirectory(atPath: paths)
        for file in fileName {
            let filePath = URL(fileURLWithPath: paths).appendingPathComponent(file).absoluteURL
            try fileManager.removeItem(at: filePath)
        }
    } catch let error {
        print(error)
    }
}

And this is what Xcode throws:
Screenshot 2024-09-05 at 6 05 50 PM
What could be the possible reason?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions