hinali lad
hinali lad

Reputation: 73

While I keep my wrist down, how to keep playing audio in iWatch app? - watchOS

I am trying to build an audio app for apple watch. But the problem is whenever I keep my hands down , audio will stop playing. I have turned background mode on as well. Can anyone please help me with this? I am stuck at this part. Here is the Code I have used for playing audio.

func play(url : URL) {
        do {
            if #available(watchOSApplicationExtension 4.0, *) {
                WKExtension.shared().isFrontmostTimeoutExtended = true
            } else {
                // Fallback on earlier versions
            }
            self.player = try AVAudioPlayer(contentsOf: url)
                player!.prepareToPlay()
            player?.delegate = self
            player?.play()
            print("-----------------")
            print("Playing Audio")
            print("*****************\nCurrent Time \(String(describing: self.player?.currentTime))")
        } catch let error as NSError {
            self.player = nil
            print(error.localizedDescription)
        } catch {
            print("*************************")
            print("AVAudioPlayer init failed")
        }
    }

Upvotes: 4

Views: 1424

Answers (2)

Ketan Sodvadiya
Ketan Sodvadiya

Reputation: 514

Make sure you are trying to play with Audio Data, not Audio URL and have added policy: .longFormAudio in your category setup. As per Apple documentation, these two settings have to be set for audio to play in background mode.

// Set up the session. 
let session = AVAudioSession.sharedInstance()
    
do {
    try session.setCategory(
        .playback,
        mode: .default,
        policy: .longFormAudio
    ) 
} catch let error {
    fatalError("*** Unable to set up the audio session: \(error.localizedDescription) ***") 
}
    
// Set up the player. 

let player: AVAudioPlayer 
do {
    player = try AVAudioPlayer(data: audioData) 
} catch let error {
    print("*** Unable to set up the audio player: \(error.localizedDescription) ***")
    // Handle the error here.
    return 
}
    
// Activate and request the route. 
session.activate(options: []) { (success, error) in
    guard error == nil else {
        print("*** An error occurred: \(error!.localizedDescription) ***")
        // Handle the error here.
        return
    }
        
    // Play the audio file.
    player.play() 
}

I have tested this code and its working with only Bluetooth connectivity in Watch application not in watch speaker.

Upvotes: 2

staticVoidMan
staticVoidMan

Reputation: 20274

Simply turning on background mode is not enough. You also need to activate the AVAudioSession.
It's all well documented by Apple here: Playing Background Audio.

Configure and Activate the Audio Session

Before you can play audio, you need to set up and activate the audio session.

session.setCategory(AVAudioSession.Category.playback,
                    mode: .default,
                    policy: .longForm,
                    options: [])

Next, activate the session, by calling the activate(options:completionHandler:) method.

session.activate(options: []) { (success, error) in
    // Check for an error and play audio.
}

Ref: https://developer.apple.com/documentation/watchkit/playing_background_audio


Example:

var player: AVAudioPlayer?
let session: AVAudioSession = .sharedInstance()

func prepareSession() {
    do {
        try session.setCategory(AVAudioSession.Category.playback,
                                mode: .default,
                                policy: .longForm,
                                options: [])
    }
    catch {
        print(error)
    }
}

func play(url: URL) {
    do {
        player = try AVAudioPlayer(contentsOf: url)
    }
    catch {
        print(error)
        return
    }

    session.activate(options: []) { (success, error) in
        guard error == nil else {
            print(error!)
            return
        }

        // Play the audio file
        self.player?.play()
    }
}

Simple Test:

prepareSession()

if let url = Bundle.main.url(forResource: "test", withExtension: "mp3") {
    play(url: url)
}
else {
    print("test.mp3 not found in project: put any mp3 file in and name it so")
}

Upvotes: 1

Related Questions