Files
terebi/Sources/Launcher/FFmpegRuntime.swift
T
hl-valdemar 31c4759c1d build: bundle playback and YouTube dependencies
Build pinned LGPL playback libraries and package standalone YouTube helpers inside the signed native app. Keep the CLI inside the app and relocate private library links for installation without runtime Homebrew dependencies.

Record adaptive fixture completion in its EXIT trap: cancellation can exit with status 143 before the TERM trap writes its marker, while native pause and quality preservation remain correct.
2026-10-12 01:52:51 +02:00

42 lines
2.2 KiB
Swift

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<String> = ["libavformat", "libavcodec", "libavutil", "libswresample", "libswscale"]
guard paths.count == libraries.count else { return metadataError }
var found = Set<String>()
for path in paths {
guard !path.contains("/"), !path.contains("\0"), !path.contains("\r") else {
return metadataError
}
let parts = URL(fileURLWithPath: path).lastPathComponent.split(separator: ".", omittingEmptySubsequences: false)
guard parts.count >= 3, 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
}
}
let frameworks = app.appendingPathComponent("Contents/Frameworks", isDirectory: true)
for filename in paths {
let path = frameworks.appendingPathComponent(filename).path
_ = 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 "This app's bundled FFmpeg libraries are missing or broken.\n\nRequired library: \(filename)\n\(detail)\n\nRebuild and reinstall terebi, or reinstall a complete bundled app."
}
// Deliberately never dlclose: retain successful loads until exit.
}
return nil
}
}