Objective C / IOS - 将音频流保存到文件

时间:2015-12-24 13:28:03

标签: ios objective-c xcode file audio

是否可以/有没有办法将音频流保存到本地文件?我非常缺乏经验,我不知道从哪里开始 - 正确的方向上的一点将不胜感激。

我正在构建一个从网址流式传输音频的应用(例如http://audiostream.mp3)。我希望用户能够将音频保存到文件中,从他们开始收听时完成。由于音频将是一个流,我担心的是我没有处理完整的mp3文件 - 我猜这会让事情比简单地下载一个完整的mp3更棘手。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可以在播放时同时保存缓冲的歌曲。

  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];

答案 1 :(得分:0)

您可以无限期保存实时音频流。您需要使用ResourceLoaderURlSessionDataTask

这是一个棘手的过程,所以我将逐步解释:

  1. 制作AVURLAsset:

    let asset = AVURLAsset(url: urlWithCustomScheme)
    
  2. 设置代表:

    asset.resourceLoader.setDelegate(resourceLoaderDelegate, queue: DispatchQueue.main)
    
  3. 以下委托函数将被调用:

    func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool
    
  4. 现在在此函数内,我们将调用一个函数来启动数据请求,以便可以开始下载声音缓冲区:

    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()
    }
    

    如您所见,我们已经打开了输出流。我们将使用此流将缓冲区写入磁盘。

  5. 现在,当我们使用给定的URL启动dataTask时,我们将开始将数据字节接收到委托函数中:

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
    
  6. 现在我们已经开始接收实时音频流。最后一个难题是存储音频流。这是最简单的部分。我们只是创建一个OutputStream对象,将其打开,然后在上面的委托函数中附加要接收的字节,就这样,我们保存了实时音频流的所需部分。

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        let bytesWritten = data.withUnsafeBytes{outputStream?.write($0, maxLength: data.count)}
        print("bytes written :\(bytesWritten!) to \(fileURL)")
    }
    

这是我在Medium博客上写的源代码,可以解决您遇到的问题:https://github.com/pandey-mohan/LiveAudioCapture

相关问题