import Foundation import Darwin enum FFmpegRuntime { static func error(for app: URL) -> String? { let manifest = app.appendingPathComponent("Contents/Resources/ffmpeg-libraries.txt") let metadataError = "This app's FFmpeg library metadata is missing or invalid. Rebuild and reinstall terebi." guard let contents = try? String(contentsOf: manifest, encoding: .utf8) else { return metadataError } var paths = contents.components(separatedBy: "\n") if paths.last == "" { paths.removeLast() } let libraries: Set = ["libavformat", "libavcodec", "libavutil", "libswresample", "libswscale"] guard paths.count == libraries.count else { return metadataError } var found = Set() for path in paths { guard path.hasPrefix("/"), !path.contains("\0"), !path.contains("\r") else { return metadataError } let parts = URL(fileURLWithPath: path).lastPathComponent.split(separator: ".", omittingEmptySubsequences: false) guard parts.count >= 2, parts.last == "dylib" else { return metadataError } let library = String(parts[0]) guard libraries.contains(library), parts.dropFirst().dropLast().allSatisfy({ !$0.isEmpty && $0.utf8.allSatisfy { (48...57).contains($0) } }), found.insert(library).inserted else { return metadataError } } for path in paths { _ = dlerror() guard dlopen(path, RTLD_NOW | RTLD_LOCAL) != nil else { let detail = dlerror().map { String(cString: $0) } ?? "The dynamic loader could not load this library." return "The FFmpeg libraries required by this build are unavailable or broken.\n\nRequired library: \(path)\n\(detail)\n\nInstall FFmpeg with `brew install ffmpeg`. If FFmpeg was upgraded or its library versions changed, rebuild and reinstall terebi." } // Deliberately never dlclose: retain successful loads until exit or bootstrap exec. } return nil } }