十进制字节数组转可播放MP3:Swift iOS客户端技术问题
问题解决思路
核心问题:你从API拿到的不是MP3的二进制数据,而是十进制字节数组的文本字符串(比如"210, 107, 180, 171..."),直接写入文件会把这些数字的文本编码保存,自然无法被音频播放器识别。
解决步骤
- 将获取到的
Data转换为字符串,提取其中的十进制数字 - 将每个数字转换为
UInt8类型的字节(MP3的原始字节就是8位无符号整数) - 把转换后的字节数组重新包装成
Data,再写入文件
修改后的代码
func getAudioRawData() async throws { guard let url = URL(string: "http://192.168.1.104:8080/audio") else { fatalError("Missing URL") } let urlRequest = URLRequest(url: url) let (data, response) = try await URLSession.shared.data(for: urlRequest) guard (response as? HTTPURLResponse)?.statusCode == 200 else { fatalError("Error while fetching data") } // 关键:解析文本格式的字节数组为二进制Data guard let byteString = String(data: data, encoding: .utf8) else { fatalError("Failed to convert response data to string") } // 分割字符串为单个数字字符串,过滤空值 let numberStrings = byteString.components(separatedBy: [",", " "]).filter { !$0.isEmpty } // 转换为UInt8字节数组,处理转换失败的情况 var audioBytes = [UInt8]() for numStr in numberStrings { guard let num = UInt8(numStr) else { print("Invalid byte value: \(numStr)") continue } audioBytes.append(num) } // 将字节数组转为真正的MP3二进制Data let audioData = Data(audioBytes) // 写入文件 print(writeToFile(data: audioData, fileName: "output")) } // writeToFile函数保持不变 func writeToFile(data: Data, fileName: String) -> URL? { guard let directory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { return nil } let fileurl = directory.appendingPathComponent("\(fileName).mp3") if FileManager.default.fileExists(atPath: fileurl.path) { if let fileHandle = FileHandle(forWritingAtPath: fileurl.path) { fileHandle.seekToEndOfFile() fileHandle.write(data) fileHandle.closeFile() } else { print("Can't open file to write.") } } else { do { try data.write(to: fileurl, options: .atomic) } catch { print("Unable to write in new file.") } } return directory }
额外说明
- 如果服务器可以修改,建议直接返回MP3的二进制数据(设置响应头
Content-Type: audio/mpeg),这样客户端无需额外解析,直接写入文件即可播放,效率更高。 - 解析过程中加入了错误处理,避免单个无效数字导致整个转换失败。
内容的提问来源于stack exchange,提问作者sivafe9540
相关产品推荐
相关产品推荐

