使用ShareLink分享m4a音频文件,除VLC外其他应用无法识别播放
解决方案
1. 检查并补全音频文件元数据
iOS系统自带应用依赖完整的标准元数据识别音频,VLC兼容性强能忽略元数据缺失问题。可以用AVFoundation检查文件是否包含关键元数据:
import AVFoundation func checkAudioMetadata(url: URL) { let asset = AVURLAsset(url: url) guard let track = asset.tracks(withMediaType: .audio).first, let formatDesc = track.formatDescriptions.first as? CMFormatDescription, let audioFormat = CMAudioFormatDescriptionGetStreamBasicDescription(formatDesc)?.pointee else { print("元数据缺失") return } print("采样率: \(audioFormat.mSampleRate)") print("声道数: \(audioFormat.mChannelsPerFrame)") print("比特率: \(asset.estimatedDataRate)") }
如果元数据缺失,建议重新导出音频文件,比如用AVAssetExportSession导出时保留原资产元数据:
let exportSession = AVAssetExportSession(asset: sourceAsset, presetName: AVAssetExportPresetAppleM4A)! exportSession.outputFileType = .m4a exportSession.outputURL = outputUrl exportSession.metadata = sourceAsset.metadata exportSession.exportAsynchronously { // 处理导出结果 }
2. 明确指定UTI并传递文件属性
修改TransferRepresentation,用具体的UTI字符串public.mpeg-4-audio替代.mpeg4Audio,同时传递文件属性帮助系统识别:
@available(iOS 16.0, *) static var transferRepresentation: some TransferRepresentation { FileRepresentation(contentType: .init("public.mpeg-4-audio")) { audio in let attributes = FileManager.default.attributesOfItem(atPath: audio.audioUrl.path) ?? [:] return SentTransferredFile(audio.audioUrl, attributes: attributes) } importing: { received in let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let copy = documentsPath.appendingPathComponent(received.file.lastPathComponent) try FileManager.default.copyItem(at: received.file, to: copy) return Self.init(audioUrl: copy) } }
3. 同时提供文件和数据两种分享表示
部分应用更倾向于接收数据而非文件链接,同时添加DataRepresentation提升兼容性:
@available(iOS 16.0, *) static var transferRepresentation: some TransferRepresentation { // 文件表示 FileRepresentation(contentType: .init("public.mpeg-4-audio")) { audio in SentTransferredFile(audio.audioUrl) } importing: { received in let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let copy = documentsPath.appendingPathComponent(received.file.lastPathComponent) try FileManager.default.copyItem(at: received.file, to: copy) return Self.init(audioUrl: copy) } // 数据表示 DataRepresentation(contentType: .init("public.mpeg-4-audio")) { audio in try Data(contentsOf: audio.audioUrl) } importing: { data in let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileName = "shared_audio_\(UUID().uuidString).m4a" let url = documentsPath.appendingPathComponent(fileName) try data.write(to: url) return Self.init(audioUrl: url) } }
内容的提问来源于stack exchange,提问作者xcoder
相关产品推荐
相关产品推荐

