Search code examples
swiftuiavfoundation

playing a url link instead of a .mp3 file in swiftui


I have made a simple swift audio view using AVFoundation. the code works for downloaded files but I do not want the app size to be very large. is it possible if i can ply it from a URL link instead?

my code is

import SwiftUI
import AVFoundation
import AVFAudio

struct AudioTest: View {
    
    @State var song1 = false
    
    var body: some View {
        Image(systemName: song1 ? "pause.circle.fill": "play.circle.fill")
            .font(.system(size: 25))
            .padding(.trailing)
            .onTapGesture {
                playSound(sound: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", type: "mp3")
                song1.toggle()
                
                if song1{
                    
                    audioPlayer1?.play()
                } else {
                    audioPlayer1?.pause()
                    
                }
        }
    }
}

struct AudioTest_Previews: PreviewProvider {
    static var previews: some View {
        AudioTest()
    }
}

var audioPlayer1: AVAudioPlayer?

func playSound1(sound: String, type:String){
    if let path = Bundle.main.path(forResource: sound, ofType: type) {
        do{
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
            //audioPlayer?.numberOfLoops = -1
            
        }catch{
            print(error)
        }
    }
}


Solution

  • You can use AVPlayer to stream resources from a URL like this. I'd also move the streaming/async logic into an ObservableObject:

    
    class SoundManager : ObservableObject {
        var audioPlayer: AVPlayer?
    
        func playSound(sound: String){
            if let url = URL(string: sound) {
                self.audioPlayer = AVPlayer(url: url)
            }
        }
    }
    
    struct ContentView: View {
        @State var song1 = false
        @StateObject private var soundManager = SoundManager()
        
        var body: some View {
            Image(systemName: song1 ? "pause.circle.fill": "play.circle.fill")
                .font(.system(size: 25))
                .padding(.trailing)
                .onTapGesture {
                    soundManager.playSound(sound: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3")
                    song1.toggle()
                    
                    if song1{
                        soundManager.audioPlayer?.play()
                    } else {
                        soundManager.audioPlayer?.pause()
                    }
            }
        }
    }