2017-10-21 97 views
2

Je souhaite autoriser l'audio d'arrière-plan lorsque l'application n'est pas active. J'ai actuellement ce code, qui devrait permettre que:Autorisation de l'audio d'arrière-plan lorsque Swift ne fonctionne pas

do { 
    try AKSettings.setSession(category: .playback, with: .mixWithOthers) 
} catch { 
    print("error") 
} 
AKSettings.playbackWhileMuted = true 

J'ai aussi le réglage « Audio, Airplay et image dans l'image » activée dans les paramètres des capacités. Cependant, lorsque j'appuie sur le bouton d'accueil de mon appareil, l'audio ne continue pas à jouer. Qu'est-ce que je fais mal? J'utilise AudioKit pour produire des sons si cela compte. J'utilise un singleton pour héberger tous les composants AudioKit que j'ai nommés AudioPlayer.swift. Voici ce que j'ai dans mon AudioPlayer.swift fichier singleton:

class AudioPlayer: NSObject { 
    var currentFrequency = String() 
    var soundIsPlaying = false 

    var leftOscillator = AKOscillator() 
    var rightOscillator = AKOscillator() 

    var rain = try! AKAudioFile() 
    var rainPlayer: AKAudioPlayer! 

    var envelope = AKAmplitudeEnvelope() 

    override init() { 
     super.init() 

     do { 
      try AKSettings.setSession(category: .playback, with: .mixWithOthers) 
     } catch { 
      print("error") 
     } 
     AKSettings.playbackWhileMuted = true 

     AudioKit.output = envelope 
     AudioKit.start() 
    } 

    func setupFrequency(left: AKOscillator, right: AKOscillator, frequency: String) { 
     currentFrequency = frequency 

     leftOscillator = left 
     rightOscillator = right 

     let leftPanner = AKPanner(leftOscillator) 
     leftPanner.pan = -1 

     let rightPanner = AKPanner(rightOscillator) 
     rightPanner.pan = 1 

     //Set up rain and rainPlayer 
     do { 
      rain = try AKAudioFile(readFileName: "rain.wav") 
      rainPlayer = try AKAudioPlayer(file: rain, looping: true, deferBuffering: false, completionHandler: nil) 
     } catch { print(error) } 

     let mixer = AKMixer(leftPanner, rightPanner, rainPlayer) 

     //Put mixer in sound envelope 
     envelope = AKAmplitudeEnvelope(mixer) 
     envelope.attackDuration = 2.0 
     envelope.decayDuration = 0 
     envelope.sustainLevel = 1 
     envelope.releaseDuration = 0.2 

     //Start AudioKit stuff 
     AudioKit.output = envelope 
     AudioKit.start() 
     leftOscillator.start() 
     rightOscillator.start() 
     rainPlayer.start() 
     envelope.start() 
     soundIsPlaying = true 
    } 
} 

Et voici un exemple d'un de mes contrôleurs sonores de vue de l'effet, qui font référence à la singleton AudioKit pour envoyer une certaine fréquence (je sur une douzaine de ces contrôleurs vue, chacun avec ses propres réglages de fréquence):

class CalmView: UIViewController { 
    let leftOscillator = AKOscillator() 
    let rightOscillator = AKOscillator() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     leftOscillator.amplitude = 0.3 
     leftOscillator.frequency = 220 

     rightOscillator.amplitude = 0.3 
     rightOscillator.frequency = 230 
    } 

    @IBAction func playSound(_ sender: Any) { 
     if shared.soundIsPlaying == false { 
      AudioKit.stop() 
      shared.setupFrequency(left: leftOscillator, right: rightOscillator, frequency: "Calm") 
     } else if shared.soundIsPlaying == true && shared.currentFrequency != "Calm" { 
      AudioKit.stop() 
      shared.leftOscillator.stop() 
      shared.rightOscillator.stop() 
      shared.rainPlayer.stop() 
      shared.envelope.stop() 
      shared.setupFrequency(left: leftOscillator, right: rightOscillator, frequency: "Calm") 
     } else { 
      shared.soundIsPlaying = false 
      shared.envelope.stop() 
     } 
    } 
} 

J'instancié singleton AudioPlayer dans mon fichier ViewController.swift.

+1

Il y a une ligne fine entre avoir assez de code et avoir trop. La question que vous avez posée a été répondue ci-dessous. Vous semblez avoir des choses correctement configurées. Testez l'exemple AudioKit SongProcessor pour voir s'il se comporte comme il le devrait et ensuite comparez votre code à celui-ci. Il n'y a pas de raccourcis et de solutions faciles parfois. –

Répondre

2

Cela dépend du moment où vous faites votre configuration par rapport au démarrage d'AudioKit. Si vous utilisez AudioKit, vous devriez utiliser son AKSettings pour gérer votre catégorie de session. Fondamentalement, non seulement la catégorie de lecture mais aussi mixWithOthers. Par défaut, est-ce:

/// Set the audio session type 
@objc open static func setSession(category: SessionCategory, 
          with options: AVAudioSessionCategoryOptions = [.mixWithOthers]) throws { 

Alors vous feriez quelque chose comme ça dans votre ViewController:

do { 
     if #available(iOS 10.0, *) { 
      try AKSettings.setSession(category: .playAndRecord, with: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP]) 
     } else { 
      // Fallback on earlier versions 
     } 
    } catch { 
     print("Errored setting category.") 
    } 

Je pense donc est une question de droit qui se. Cela peut également aider à configurer l'audio inter-applications. Si vous avez encore des problèmes et que vous fournissez plus d'informations, je peux vous aider davantage, mais c'est une bonne réponse que je peux rassembler sur la base de l'information que vous avez donnée jusqu'à présent.

+0

Dois-je démarrer AudioKit après la configuration de ces paramètres ou avant? En ce moment j'ai ce code dans mon ViewController.swift mais je démarre AudioKit dans un autre contrôleur de vue. Cela pourrait-il causer le problème? – 5AMWE5T

+1

AudioKit remplacera probablement le paramètre que vous êtes en train de faire si vous le faites en premier. Je ne suggère pas de faire de l'audio dans les contrôleurs de vue. Au lieu de cela, créez une classe singleton pour votre audio - parfois nous l'appellerons le moteur ou le conducteur, et y référer à partir de tous vos contrôleurs de vue. Vous ne voulez pas que le cycle de vie du contrôleur de vue affecte l'état de votre moteur audio. –

+0

J'ai mon lecteur audio dans un singleton et j'ai déplacé le code de mon post original, mais le problème est toujours là. – 5AMWE5T