-2

Я пытаюсь разрешить пользователю выбирать песню из своей библиотеки и воспроизводить ее через разные контроллеры представлений. Я могу выбирать песни в настоящее время и играть в них, но я не знаю, как играть их в фоновом режиме. Благодаря!Как играть музыку в фоновом режиме в Swift с помощью MPMediaPickerController?

class ViewController: UIViewController, 
MPMediaPickerControllerDelegate, AVAudioPlayerDelegate { 


    var myMusicPlayer: MPMusicPlayerController? 
    var mediaPicker: MPMediaPickerController? 
    var backgroundMusicPlayer:AVAudioPlayer = AVAudioPlayer() 


    @IBAction func musicBtn(sender: AnyObject) { 
     displayMediaPickerAndPlayItem() 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 

    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


    /* 
    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     // Get the new view controller using segue.destinationViewController. 
     // Pass the selected object to the new view controller. 
    } 
    */ 



    func musicPlayerStateChanged(notification: NSNotification){ 

     print("Player State Changed") 

     /* Let's get the state of the player */ 
     let stateAsObject = 
      notification.userInfo!["MPMusicPlayerControllerPlaybackStateKey"] 
       as? NSNumber 

     if let state = stateAsObject{ 

      /* Make your decision based on the state of the player */ 
      switch MPMusicPlaybackState(rawValue: state.integerValue)!{ 
      case .Stopped: 
       /* Here the media player has stopped playing the queue. */ 
       print("Stopped") 
      case .Playing: 
       /* The media player is playing the queue. Perhaps you 
       can reduce some processing that your application 
       that is using to give more processing power 
       to the media player */ 
       print("Paused") 
      case .Paused: 
       /* The media playback is paused here. You might want 
       to indicate by showing graphics to the user */ 
       print("Paused") 
      case .Interrupted: 
       /* An interruption stopped the playback of the media queue */ 
       print("Interrupted") 
      case .SeekingForward: 
       /* The user is seeking forward in the queue */ 
       print("Seeking Forward") 
      case .SeekingBackward: 
       /* The user is seeking backward in the queue */ 
       print("Seeking Backward") 
      } 

     } 
    } 

    func nowPlayingItemIsChanged(notification: NSNotification){ 

     print("Playing Item Is Changed") 

     let key = "MPMusicPlayerControllerNowPlayingItemPersistentIDKey" 

     let persistentID = 
      notification.userInfo![key] as? NSString 

     if let id = persistentID{ 
      /* Do something with Persistent ID */ 
      print("Persistent ID = \(id)") 
     } 

    } 

    func volumeIsChanged(notification: NSNotification){ 
     print("Volume Is Changed") 
     /* The userInfo dictionary of this notification is normally empty */ 
    } 

    func mediaPicker(mediaPicker: MPMediaPickerController, 
        didPickMediaItems mediaItemCollection: MPMediaItemCollection){ 

     print("Media Picker returned") 

     /* Instantiate the music player */ 

     myMusicPlayer = MPMusicPlayerController() 

     if let player = myMusicPlayer{ 

      player.beginGeneratingPlaybackNotifications() 

      /* Get notified when the state of the playback changes */ 
      NSNotificationCenter.defaultCenter().addObserver(self, 
                  selector: "musicPlayerStateChanged:", 
                  name: MPMusicPlayerControllerPlaybackStateDidChangeNotification, 
                  object: nil) 

      /* Get notified when the playback moves from one item 
      to the other. In this recipe, we are only going to allow 
      our user to pick one music file */ 
      NSNotificationCenter.defaultCenter().addObserver(self, 
                  selector: "nowPlayingItemIsChanged:", 
                  name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification, 
                  object: nil) 

      /* And also get notified when the volume of the 
      music player is changed */ 
      NSNotificationCenter.defaultCenter().addObserver(self, 
                  selector: "volumeIsChanged:", 
                  name: MPMusicPlayerControllerVolumeDidChangeNotification, 
                  object: nil) 

      /* Start playing the items in the collection */ 
      player.setQueueWithItemCollection(mediaItemCollection) 
      player.play() 

      /* Finally dismiss the media picker controller */ 
      mediaPicker.dismissViewControllerAnimated(true, completion: nil) 

     } 

    } 

    func mediaPickerDidCancel(mediaPicker: MPMediaPickerController) { 
     /* The media picker was cancelled */ 
     print("Media Picker was cancelled") 
     mediaPicker.dismissViewControllerAnimated(true, completion: nil) 
    } 

    func stopPlayingAudio(){ 

     NSNotificationCenter.defaultCenter().removeObserver(self) 

     if let player = myMusicPlayer{ 
      player.stop() 
     } 

    } 

    func displayMediaPickerAndPlayItem(){ 

     mediaPicker = MPMediaPickerController(mediaTypes: .AnyAudio) 

     if let picker = mediaPicker{ 


      print("Successfully instantiated a media picker") 
      picker.delegate = self 
      picker.allowsPickingMultipleItems = true 
      picker.showsCloudItems = true 
      picker.prompt = "Pick a song please..." 
      view.addSubview(picker.view) 

      presentViewController(picker, animated: true, completion: nil) 

     } else { 
      print("Could not instantiate a media picker") 
     } 

    } 

} 

ответ

0

Вы можете использовать синглтон, чтобы достичь его, как это:

import AVFoundation 

class MusicHelper { 
    static let sharedHelper = MusicHelper() 
    var audioPlayer: AVAudioPlayer? 

    func playBackgroundMusic() { 
     let pickedSong = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("userPickedSong", ofType: "mp3")!) 
     do { 
      audioPlayer = try AVAudioPlayer(contentsOfURL:aSound) 
      audioPlayer!.numberOfLoops = -1 
      audioPlayer!.prepareToPlay() 
      audioPlayer!.play() 
     } catch { 
      print("Cannot play the file") 
     } 
    } 
} 

И вы можете использовать его как это:

MusicHelper.sharedHelper.playBackgroundMusic() 

Это только один пример того, как вы можете это сделать. На самом деле их больше, и на StackOverflow уже есть ответы. Но так, как я показал, вы можете назвать это в любом классе.

+0

Благодарим за помощь. Будет ли способ включить это с помощью mpmediapickercontroller? Таким образом, пользователь может выбрать песню из своей библиотеки. – Brandex07

+0

Конечно. Вы должны реализовать его, чтобы позволить избранным. –

+0

Хмм ты не возражаешь, показывая мне, как? благодаря – Brandex07

2

Если вы хотите играть «через разные контроллеры», тогда не ставьте AVAudioPlayer в один контроллер. Если вы это сделаете, он будет уничтожен, когда вы покинете этот контроллер.

Поместите аудиоплеер где-нибудь, что сохранится независимо от того, как, например, ваш делегат приложения.