简体   繁体   中英

Objective C/IOS - Save Audio Stream To File

Is it possible/Is there a way to save an audio stream to a local file? I'm very inexperienced and I dont know where to start -- a point in the right direction would be appreciated.

I'm building an app that streams audio from URLs (eg http://audiostream.mp3 ). I'd like the user to be able to save audio, to a file, from when they start listening to when they finish. As the audio will be a stream, my concern is that i'm not dealing with a complete mp3 file -- i'm guessing this makes things trickier than simply downloading a complete mp3.

Thanks in advance for your help with this.

You can save the buffered song at the same time when it is played.

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

You can save live audio stream with indefinite duration. You need to use ResourceLoader and URlSessionDataTask .

It's a bit tricky process, so I will explain step by step:

  1. Making an AVURLAsset:

     let asset = AVURLAsset(url: urlWithCustomScheme) 
  2. Set the delegate:

     asset.resourceLoader.setDelegate(resourceLoaderDelegate, queue: DispatchQueue.main) 
  3. Following delegate function will be called:

     func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool 
  4. Now inside this function we will call a function to start the data request, so that downloading of sound buffer can start:

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

    as you can see we have opened a output stream. We will use this stream to write buffer to our disk.

  5. Now as we initiated a dataTask with the given URL, we will start receiving data bytes into the delegate function:

     func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) 
  6. Now we have started receiving live audio stream. Last piece of the puzzle is to store the audio stream. It is the simplest part. We just create an OutputStream object, open it then append the bytes we are receiving in the above delegate function and thats it, we saved the desired part of the live audio stream.

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

Here is the source code that I wrote on a blog in Medium, solving the problem that you faced: https://github.com/pandey-mohan/LiveAudioCapture

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM