Jacob Cavin
Jacob Cavin

Reputation: 2319

AVAudioEngine Cannot Create AVAudioFile from URL

I cannot seem to create an AVAudioFile from a URL to be played in an AVAudioEngine. Here is my complete code, following Apple's documentation.

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    let audioEngine = AVAudioEngine()
    let audioPlayerNode = AVAudioPlayerNode()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        streamAudioFromURL(urlString: "https://samplelib.com/lib/preview/mp3/sample-9s.mp3")
        
    }
    
  
    func streamAudioFromURL(urlString: String) {
        guard let url = URL(string: urlString) else {
            print("Invalid URL")
            return
        }
        
        let audioFile = try! AVAudioFile(forReading: url)
        let audioEngine = AVAudioEngine()
        let playerNode = AVAudioPlayerNode()

        audioEngine.attach(playerNode)

        audioEngine.connect(playerNode,
                            to: audioEngine.outputNode,
                            format: audioFile.processingFormat)
        playerNode.scheduleFile(audioFile,
                                at: nil,
                                completionCallbackType: .dataPlayedBack) { _ in
            /* Handle any work that's necessary after playback. */
        }
        do {
            try audioEngine.start()
            playerNode.play()
        } catch {
            /* Handle the error. */
        }
        
    }
    
}

I am getting the following error on let audioFile = try! AVAudioFile(forReading: url)

Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=com.apple.coreaudio.avfaudio Code=2003334207 "(null)" UserInfo={failed call=ExtAudioFileOpenURL((CFURLRef)fileURL, &_extAudioFile)}

I have tried many other .mp3 file URLs as well as .wav and .m4a and none seem to work. The documentation makes this look so easy but I have been trying for hours to no avail. If you have any suggestions, they would be greatly appreciated!

Upvotes: 1

Views: 702

Answers (1)

soundflix
soundflix

Reputation: 2763

class AVAudioFile is for local files only.

See here: URL is nil in AVAudioFile

You cannot call AVAudioFile(forReading:) on a remote file. You need to download the binary data and parse it into packets using audio file stream services. That way, you can supply the packets to a buffer and play from the buffer thru the audio engine.

If you intend to just stream single audio streams, use the much simpler : AVPlayer

Upvotes: 1

Related Questions