Shark Deng
Shark Deng

Reputation: 1058

Why AVAudioPlayer has no sound?

I got one button which can play and pause the audio, but I found the following code has no sound. Do you know why? If I put the AVAudioPlayer create code snippet in a dependent function playAudio(), it can play the sound but I cannot pause and continue playing.

Reproducible code

import SwiftUI
import AVFoundation


struct ContentView: View {
    var shortname: String
    var id: Int
    @State var audioPlayer: AVAudioPlayer?
    
    
    init(shortname: String="rs", id: Int=1) {
        self.shortname = shortname
        self.id = id
        
        let fileName = self.shortname.lowercased() + "-" + String(id)
        guard let path = Bundle.main.path(forResource: fileName, ofType: "mp3") else {
            print("[shark]", fileName + "is not found")
            return
        }
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
            audioPlayer?.play()
        } catch {
            print("[shark], audioPlayer cannot load", path, error)
        }
        
    }
    

    var body: some View {
        
        Text("good")
            .onAppear {
                audioPlayer?.play()
            }
    }
}

Upvotes: 1

Views: 598

Answers (1)

jnpdx
jnpdx

Reputation: 52347

SwiftUI is picky about what you can do in an initializer for a View struct like this. A more reliable option is to move the loading into an ObservableObject:

class AudioManager : ObservableObject {
    var audioPlayer : AVAudioPlayer?
    
    func loadAudio(filename: String) {
        guard let path = Bundle.main.path(forResource: filename, ofType: "mp3") else {
            print("[shark]", filename + "is not found")
            return
        }
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
        } catch {
            print("[shark], audioPlayer cannot load", path, error)
        }
    }
    
    func playAudio() {
        audioPlayer?.play()
    }
}

struct ContentView: View {
    var shortname: String = ""
    var id: Int = 0
    @ObservedObject var audioManager = AudioManager()
    

    var body: some View {
        
        Text("good")
            .onAppear {
                let fileName = self.shortname.lowercased() + "-" + String(id)
                audioManager.loadAudio(filename: fileName)
                audioManager.playAudio()
            }
    }
}

This plays for me on Xcode 12.3 and iOS 14

Upvotes: 2

Related Questions