From 4aec892151c8eec45cfd6e50bac60183535a54ae Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 17 Jul 2026 21:14:36 +0800 Subject: [PATCH] fix(iOS): add copyLocalFile for local file recording on iOS HLSRecorder.recordStream() now checks url.isFileURL first and copies locally instead of using URLSession.download() which only works for http/https URLs. Fixes recording local mp4 files on iOS. --- Sources/HLSRecorder.swift | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Sources/HLSRecorder.swift b/Sources/HLSRecorder.swift index 9185c7c..da92dce 100644 --- a/Sources/HLSRecorder.swift +++ b/Sources/HLSRecorder.swift @@ -73,6 +73,12 @@ final class HLSRecorder: ObservableObject { // MARK: - 核心录制逻辑 private func recordStream(url: URL) async throws -> URL { + // 本地文件直接复制,不走网络下载 + if url.isFileURL { + NSLog("[MiniPlayer] recordStream: local file, copying directly") + return try await copyLocalFile(url: url) + } + // 判断是否为 HLS(m3u8 扩展名或 URL 含 m3u8 参数) let ext = url.pathExtension.lowercased() let isHLS = ext == "m3u8" @@ -230,8 +236,23 @@ final class HLSRecorder: ObservableObject { return outputURL } - // MARK: - 普通文件下载 - + // MARK: - 本地文件复制 / 网络下载 + + private func copyLocalFile(url: URL) async throws -> URL { + let ext = url.pathExtension.isEmpty ? "mp4" : url.pathExtension + let outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] + .appendingPathComponent("MiniPlayer_Recording_\(Int(Date().timeIntervalSince1970)).\(ext)") + + if FileManager.default.fileExists(atPath: outputURL.path) { + try FileManager.default.removeItem(at: outputURL) + } + try FileManager.default.copyItem(at: url, to: outputURL) + NSLog("[MiniPlayer] copyLocalFile: %@ → %@ (%lld bytes)", + url.lastPathComponent, outputURL.lastPathComponent, + (try? FileManager.default.attributesOfItem(atPath: outputURL.path)[.size] as? Int64) ?? 0) + return outputURL + } + private func downloadFile(url: URL) async throws -> URL { let ext = url.pathExtension.isEmpty ? "mp4" : url.pathExtension let outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]