import Foundation import CommonCrypto import CryptoKit /// Native counterpart of MegaPlay's deployed e1-player and newclient codecs. struct MiruroEmbed: Sendable { let url: URL // Public embed-origin headers apply to its cross-origin media resources too: // deployed CDN segment endpoints reject requests without this Referer. let headers: String private let key: Data private let iv: Data static func resolve(url: URL, now: @Sendable () -> Date = { Date() }) async throws -> MiruroEmbed { do { try validateOrigin(url) let configuration = URLSessionConfiguration.ephemeral configuration.timeoutIntervalForRequest = 25 configuration.timeoutIntervalForResource = 25 configuration.httpShouldSetCookies = false configuration.httpCookieStorage = nil configuration.urlCache = nil let session = URLSession(configuration: configuration, delegate: EmbedRedirectPolicy(), delegateQueue: nil) defer { session.invalidateAndCancel() } let html = try await text(url, session: session) guard let player = capture(#"<[^>]+\bid\s*=\s*["']megaplay-player["'][^>]*>"#, html), let id = capture(#"\bdata-id\s*=\s*["']([^"']+)["']"#, player), let base = capture(#"\bbase_url\s*:\s*["']([^"']+)["']"#, html), let baseURL = URL(string: base.replacingOccurrences(of: "\\/", with: "/"), relativeTo: url)?.absoluteURL else { throw EmbedError() } try validateOrigin(baseURL) // Only read script data; never evaluate provider JavaScript. let scripts = captures(#"]*\bsrc\s*=\s*["']([^"']+)["']"#, html) guard let scriptURL = scripts.compactMap({ URL(string: $0, relativeTo: url)?.absoluteURL }) .first(where: { $0.path.hasSuffix("/e1-player.min.js") }) else { throw EmbedError() } try validateOrigin(scriptURL) let script = try await text(scriptURL, session: session) guard let keyText = capture(#"\bSOURCE_ENC_KEY\s*=\s*"([^"\\]*)""#, script), let ivText = capture(#"\bSOURCE_ENC_IV\s*=\s*"([^"\\]*)""#, script), let secret = capture(#"\bCDN_TOKEN_SECRET\s*=\s*"([^"\\]*)""#, script) else { throw EmbedError() } let key = padded(keyText, count: 32) let iv = padded(ivText, count: 16) var endpoint = URLComponents(url: baseURL.appendingPathComponent("stream/getSources"), resolvingAgainstBaseURL: false) endpoint?.queryItems = [URLQueryItem(name: "id", value: id)] guard let endpointURL = endpoint?.url else { throw EmbedError() } let payload = try await request(endpointURL, session: session) guard let object = try JSONSerialization.jsonObject(with: payload) as? [String: Any], object["error"] == nil || (object["error"] as? Bool) == false else { throw EmbedError() } let source: Any if let encrypted = object["enc"] as? String { source = try JSONSerialization.jsonObject(with: decrypt(encrypted, key: key, iv: iv)) guard (source as? [String: Any])?["file"] is String else { throw EmbedError() } } else if let plain = object["sources"] { source = plain } else { throw EmbedError() } guard let file = streamFile(source), let stream = URL(string: file) else { throw EmbedError() } try validateHTTP(stream) let tokenEnabled = capture(#"\bcdnTokenEnable\s*:\s*(false|0|"false"|'false'|"0"|'0')\s*[,}]"#, html) == nil let finalURL = try attachToken(stream, secret: secret, enabled: tokenEnabled, now: now()) try Task.checkCancellation() return MiruroEmbed(url: finalURL, headers: "Referer: https://megaplay.buzz/\r\nOrigin: https://megaplay.buzz\r\n", key: key, iv: iv) } catch { if Task.isCancelled || error is CancellationError || (error as? URLError)?.code == .cancelled { throw CancellationError() } throw EmbedError() } } func resourceURL(_ url: URL) throws -> URL { try Self.validateHTTP(url) guard let token = Self.capture(#"/segment/([A-Za-z0-9_-]+)"#, url.path) else { return url } let data = try Self.decrypt(token, key: key, iv: iv) guard let text = String(data: data, encoding: .utf8), let decoded = URL(string: text) else { throw EmbedError() } try Self.validateHTTP(decoded) return decoded } func resourceData(_ data: Data, url: URL) throws -> Data { try Self.validateHTTP(url) // newclient v4.23 SegmentStrip: only these hosts, and only bodies longer than 252 bytes. guard let host = url.host, Self.capture(#"ibyteimg\.com|tiktokcdn\.com|ipstatp\.com|yoot\.akirax\.buzz"#, host) != nil, data.count > 252 else { return data } return Data(data.dropFirst(252)) } private static func request(_ url: URL, session: URLSession) async throws -> Data { try validateOrigin(url) var request = URLRequest(url: url) request.timeoutInterval = 25 request.setValue("https://megaplay.buzz/", forHTTPHeaderField: "Referer") let (bytes, response) = try await session.bytes(for: request) let limit = 2 * 1024 * 1024 guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode), response.expectedContentLength <= Int64(limit) else { throw EmbedError() } var data = Data() for try await byte in bytes { try Task.checkCancellation() guard data.count < limit else { throw EmbedError() } data.append(byte) } return data } private static func text(_ url: URL, session: URLSession) async throws -> String { let data = try await request(url, session: session) guard let text = String(data: data, encoding: .utf8) else { throw EmbedError() } return text } private static func streamFile(_ source: Any) -> String? { if let string = source as? String { return string } if let array = source as? [Any], let first = array.first { return streamFile(first) } return (source as? [String: Any])?["file"] as? String } private static func attachToken(_ url: URL, secret: String, enabled: Bool, now: Date) throws -> URL { guard var parts = URLComponents(url: url, resolvingAgainstBaseURL: false) else { throw EmbedError() } guard enabled, !(parts.queryItems ?? []).contains(where: { $0.name == "token" }), let pathKey = capture(#"/([a-f0-9]{32}/[a-f0-9]{32})/"#, url.path) else { return url } let seconds = now.timeIntervalSince1970.rounded(.down) guard seconds.isFinite, seconds >= 0, seconds < Double(Int64.max - 90) else { throw EmbedError() } let message = Data("\(Int64(seconds) + 90)|\(pathKey.lowercased())".utf8) let signature = HMAC.authenticationCode(for: message, using: SymmetricKey(data: Data(secret.utf8))) let token = base64URL(message) + "." + base64URL(Data(signature)) var items = parts.queryItems ?? [] items.append(URLQueryItem(name: "token", value: token)) parts.queryItems = items guard let result = parts.url else { throw EmbedError() } return result } private static func padded(_ string: String, count: Int) -> Data { var data = Data(string.utf8.prefix(count)) data.append(Data(repeating: 0, count: count - data.count)) return data } private static func base64URL(_ data: Data) -> String { data.base64EncodedString().replacingOccurrences(of: "+", with: "-") .replacingOccurrences(of: "/", with: "_").replacingOccurrences(of: "=", with: "") } private static func decrypt(_ token: String, key: Data, iv: Data) throws -> Data { var encoded = token.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") encoded += String(repeating: "=", count: (4 - encoded.count % 4) % 4) guard let encrypted = Data(base64Encoded: encoded), !encrypted.isEmpty, encrypted.count % kCCBlockSizeAES128 == 0 else { throw EmbedError() } var output = Data(count: encrypted.count + kCCBlockSizeAES128) let capacity = output.count var written = 0 let status = output.withUnsafeMutableBytes { destination in encrypted.withUnsafeBytes { input in key.withUnsafeBytes { keyBytes in iv.withUnsafeBytes { ivBytes in CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionPKCS7Padding), keyBytes.baseAddress, key.count, ivBytes.baseAddress, input.baseAddress, encrypted.count, destination.baseAddress, capacity, &written) } } } } guard status == kCCSuccess else { throw EmbedError() } output.count = written return output } private static func validateHTTP(_ url: URL) throws { guard ["https", "http"].contains(url.scheme?.lowercased() ?? ""), let host = url.host, !host.isEmpty, url.user == nil, url.password == nil else { throw EmbedError() } } private static func validateOrigin(_ url: URL) throws { try validateHTTP(url) guard url.scheme?.lowercased() == "https", url.host?.lowercased() == "megaplay.buzz", url.port == nil || url.port == 443 else { throw EmbedError() } } private static func capture(_ pattern: String, _ text: String) -> String? { captures(pattern, text).first } private static func captures(_ pattern: String, _ text: String) -> [String] { guard let regex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) else { return [] } return regex.matches(in: text, range: NSRange(text.startIndex..., in: text)).compactMap { match in let index = match.numberOfRanges > 1 ? 1 : 0 guard let range = Range(match.range(at: index), in: text) else { return nil } return String(text[range]) } } } private struct EmbedError: LocalizedError { var errorDescription: String? { "The embedded provider could not prepare this stream." } } private final class EmbedRedirectPolicy: NSObject, URLSessionTaskDelegate, @unchecked Sendable { func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { completionHandler(nil) } }