Objective C/IOS - 将音频流保存到文件
Posted
技术标签:
【中文标题】Objective C/IOS - 将音频流保存到文件【英文标题】:Objective C/IOS - Save Audio Stream To File 【发布时间】:2015-12-24 13:28:02 【问题描述】:有可能/有没有办法将音频流保存到本地文件?我非常缺乏经验,我不知道从哪里开始 - 一个正确方向的点将不胜感激。
我正在构建一个从 URL 流式传输音频的应用程序(例如 http://audiostream.mp3)。我希望用户能够将音频保存到文件中,从他们开始收听时开始。由于音频将是一个流,我担心的是我没有处理完整的 mp3 文件——我猜这比简单地下载完整的 mp3 更棘手。
在此先感谢您的帮助。
【问题讨论】:
如果你能得到整个文件,你应该可以trim it。如果您正在构建一个流媒体应用程序,您应该能够将其解码并保存为 mp3。 太棒了——谢谢。如果我有任何问题,我会阅读并报告:) 嗨——我还在玩这个方法。需要先尝试解决一些问题......但我可能需要回到你身边。 这个方法好像会报错:(. 嗨——对不起,我不明白你的意思。我没有完全理解,这就是我寻求指导的原因;)。这件事你能帮我吗? 【参考方案1】:您可以无限期保存实时音频流。您需要使用ResourceLoader
和URlSessionDataTask
。
这个过程有点棘手,所以我会一步一步解释:
制作一个 AVURLAsset:
let asset = AVURLAsset(url: urlWithCustomScheme)
设置委托:
asset.resourceLoader.setDelegate(resourceLoaderDelegate, queue: DispatchQueue.main)
以下委托函数将被调用:
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool
现在在这个函数内部我们将调用一个函数来开始数据请求,这样就可以开始下载声音缓冲区了:
func startDataRequest(with url: URL)
var recordingName = "default.mp3"
if let recording = owner?.recordingName
recordingName = recording
fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent(recordingName)
let configuration = URLSessionConfiguration.default
configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
session?.dataTask(with: url).resume()
outputStream = OutputStream(url: fileURL, append: true)
outputStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
outputStream?.open()
如您所见,我们打开了一个输出流。我们将使用这个流将缓冲区写入我们的磁盘。
现在,当我们使用给定的 URL 启动 dataTask 时,我们将开始将数据字节接收到委托函数中:
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
现在我们已经开始接收实时音频流了。最后一块拼图是存储音频流。这是最简单的部分。我们只需创建一个 OutputStream 对象,打开它,然后在上面的委托函数中附加我们接收到的字节,就是这样,我们保存了实时音频流的所需部分。
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
let bytesWritten = data.withUnsafeBytesoutputStream?.write($0, maxLength: data.count)
print("bytes written :\(bytesWritten!) to \(fileURL)")
这是我在 Medium 博客上写的源代码,解决了你遇到的问题:https://github.com/pandey-mohan/LiveAudioCapture
【讨论】:
【参考方案2】:您可以在播放的同时保存缓冲的歌曲。
NSData *aData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.noiseaddicts.com/samples_1w72b820/274.mp3"]];
NSError *aError;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/MyFolder.mp3"];
NSLog(@"%@",dataPath);
[aData writeToFile:dataPath atomically:YES];
aPlayer = [[AVAudioPlayer alloc]initWithData:aData error:&aError];
if (aError)
NSLog(@"Erri %@",aError.description);
aPlayer.volume = 1;
[aPlayer play];
【讨论】:
嗨——我无法让它工作。使用我的 url 时,代码停留在第一行(NSData)。我认为这是因为 URL 是一个流(如无线电广播)而不是一个完整的文件(例如一首歌曲)。你有什么想法? 你的音频文件有多大? URL是音频流;因此我猜你访问它的时间越长它就越大。以上是关于Objective C/IOS - 将音频流保存到文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 MPMoviePlayerController 将音频流保存到文件中