Playing audio file from Firebase not working

78 Views Asked by At

I'm (unsuccessfully) trying to play an audio file stored in Firebase using AVAudioPlayer.

I'm getting the following error message: Error creating audio player: The operation couldn’t be completed. (OSStatus error 2003334207.)

Here's the code for my Audio Player View Model:

class AudioPlayerViewModel: ObservableObject {
    
    private var audioPlayer: AVAudioPlayer?
    
    func playAudioFromUrl(from storagePath: String) {
        let storage = Storage.storage()
        let storageRef = storage.reference()
        let audioRef = storageRef.child(storagePath)
        
        audioRef.downloadURL { url, error in
            print(audioRef)
            guard let audioURL = url, error == nil else {
                print("Error fetching audio URL: \(error?.localizedDescription ?? "")")
                return
            }
            
            print("Audio URL: \(audioURL)")
            print("Audio URL String: \(audioURL.absoluteString)")
            
            do {
                self.audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
                self.audioPlayer?.prepareToPlay()
                self.audioPlayer?.play()
            } catch {
                print("Error creating audio player: \(error.localizedDescription)")
                if let nsError = error as NSError? {
                    print("Error code: \(nsError.code)")
                }
            }
        }
    }
    
    func stopAudio() {
        audioPlayer?.stop()
    }
}

And the code for my view:

struct PlaybackControlsView: View {
    
    var audioPath: String
    
    @ObservedObject private var audioPlayerVM = AudioPlayerViewModel()
    
    var body: some View {
        
        VStack {
            // Add UI elements here, e.g., play and stop buttons
            Button("Play Audio") {
                audioPlayerVM.playAudioFromUrl(from: "Stories/\(audioPath).mp3")
            }
            .padding()
            
            Button("Stop Audio") {
                audioPlayerVM.stopAudio()
            }
            .padding()
        }
    }
}

#Preview {
    PlaybackControlsView(audioPath: "example")
}

Not sure where I'm going wrong here. Any help would be greatly appreciated.

1

There are 1 best solutions below

0
workingdog support Ukraine On BEST ANSWER

You could try this approach using AVPlayer with a url, instead of the AVAudioPlayer that seems to only play audio data from a file or buffer.

class AudioPlayerViewModel2: ObservableObject {
    
    private var audioPlayer: AVPlayer?  // <-- here
    
    func playAudioFromUrl(from storagePath: String) {
        let storage = Storage.storage()
        let storageRef = storage.reference()
        let audioRef = storageRef.child(storagePath)

        audioRef.downloadURL { url, error in
            print(audioRef)
            guard let audioURL = url, error == nil else {
                print("Error fetching audio URL: \(error?.localizedDescription ?? "")")
                return
            }

            print("Audio URL: \(audioURL)")
            print("Audio URL String: \(audioURL.absoluteString)")

            // --- here
            let playerItem = AVPlayerItem(url: audioURL)
            self.audioPlayer = AVPlayer(playerItem: playerItem)
            self.audioPlayer?.volume = 10
            self.audioPlayer?.play()
        }
    }
    
    func stopAudio() {
        audioPlayer?.pause()
    }
}