web-dev-qa-db-fra.com

Comment faire jouer mon AVPlayer lorsque l'application est en arrière-plan?

J'ai fait mes devoirs ... j'ai lu ici les docs, googler, stackoverflowing ... mais je n'ai toujours pas eu la moindre chance de faire en sorte que mon son reste bloqué lorsque l'utilisateur fait passer l'application en arrière-plan.

Ce que j’ai fait jusqu’à présent: Ajout du fichier UIBackgroundModes, audio dans le fichier plist.

D'abord ce code:

radioAudio = [[AVAudioSession alloc] init];
[radioAudio setCategory:AVAudioSessionCategoryPlayback error:nil];
[radioAudio setActive:YES error:nil];

Ensuite ceci:

NSString *radioURL = @"http://xxx.xxx.xxx/radio.m3u";
radioPlayer = [[AVPlayer playerWithURL:[NSURL URLWithString:radioURL]] retain];

Mais dès que l'utilisateur appuie sur le bouton d'accueil, mon son s'éteint.

J'ai aussi trouvé ceci, mais pas encore ajouté, car certaines choses que j'ai lues disent que ce n'est pas nécessaire;

newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
     if (newTaskId != UIBackgroundTaskInvalid && bgTaskId != UIBackgroundTaskInvalid)
        [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
bgTaskId = newTaskId;

Pour le moment, je ne sais pas où je devrais aller pour faire en sorte que mon AVPlayer laisse la radio chanter pendant que l'utilisateur fait d'autres choses au téléphone .. Je teste cela sur un iPhone 4 avec une version 4.2. Construire pour 4.0.

Quelqu'un a des suggestions sur ce que je devrais faire?

27
swe_mattias

Avait le même problème, mais a trouvé une solution pour cela ..

Regardez ici: https://devforums.Apple.com/message/395049#395049

Le contenu du lien ci-dessus:


Remplacez APPNAME par votre propre nom d'application!

Je suis sur iOS 4.2.1

EDIT: Utilisation de iOS5 + 6 + 7 beta jusqu'à présent

Ajouter UIBackgroundModes dans le APPNAME-Info.plist, avec la sélection L'application lit l'audio

Ajoutez ensuite la structure AudioToolBox aux structures de dossiers.

Dans le APPNAMEAppDelegate.h, ajoutez:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

alors ça ressemble à ça:

...
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
...

Dans le APPNAMEAppDelegate.m, ajoutez ce qui suit:

// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];

/* Pick any one of them */
// 1. Overriding the output audio route
//UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
//AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

// 2. Changing the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

dans le

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

mais avant les deux lignes:

[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];

Construisez votre projet et voyez s’il ya une erreur. Si non, essayez de déboguer sur un périphérique installé sur le simulateur, il peut bogue sur le simulateur.

J'espère que cela aide les autres avec le même problème ..

41
Patrick R

(MISE À JOUR IOS 11.2 avec Swift 4:} _

Maintenant, si vous utilisez AVPlayer pour lire des fichiers de musique, vous devez également configurer MPNowPlayingInfoCenter.default() pour afficher les informations en cours de lecture sur l'écran de verrouillage. 

Le code ci-dessous indiquera les commandes en cours de lecture à l'écran, mais il ne pourra répondre à aucune commande. 

Si vous souhaitez également que les contrôles fonctionnent, vous devez consulter le projet exemple d'Apple ici: https://developer.Apple.com/library/content/samplecode/MPRemoteCommandSample/Introduction/Intro.html#//Apple_ref/doc/uid/ TP40017322

Le code d'échantillon Apple couvre tout mais je trouve cela déroutant.

Si vous souhaitez jouer du son et afficher les commandes sur l'écran de verrouillage, ces étapes suffiront.

NOTE IMPORTANTE: Si vous êtes PAS utilisez AVPlayer pour reproduire le son. Si vous utilisez des bibliothèques tierces pour générer du son ou lire un fichier audio, vous devez lire les commentaires dans le code. De plus, si vous utilisez ios simulator 11.2, vous ne pourrez voir aucun contrôle sur l'écran de verrouillage. Vous devriez utiliser un appareil pour le voir fonctionner.


1- Sélectionnez le projet -> les capacités -> définissez les modes d’arrière-plan sur ON -> cochez Audio, AirPlay et Picture in Picture

 ios 11 background audio setting

2- Le fichier _ AppDelegate.Swift devrait ressembler à ceci:

import UIKit

import AVFoundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        // Override point for customization after application launch.

        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

         //!! IMPORTANT !!
         /*
         If you're using 3rd party libraries to play sound or generate sound you should
         set sample rate manually here.
         Otherwise you wont be able to hear any sound when you lock screen
         */
            //try AVAudioSession.sharedInstance().setPreferredSampleRate(4096)
        }
        catch
        {
            print(error)
        }
        // This will enable to show nowplaying controls on lock screen
        application.beginReceivingRemoteControlEvents()

        return true
    }
}

3- (ViewController.Swift} devrait ressembler à ceci:

import UIKit

import AVFoundation
import MediaPlayer

class ViewController: UIViewController
{

    var player : AVPlayer = AVPlayer()

    override func viewDidLoad()
    {
        super.viewDidLoad()


        let path = Bundle.main.path(forResource: "music", ofType: "mp3")
        let url = URL(fileURLWithPath: path!)

        // !! IMPORTANT !!
        /*
            If you are using 3rd party libraries to play sound 
            or generate sound you should always setNowPlayingInfo 
            before you create your player object.

            right:
            self.setNowPlayingInfo()
            let notAVPlayer = SomePlayer()

            wrong(You won't be able to see any controls on lock screen.):
            let notAVPlayer = SomePlayer()
            self.setNowPlayingInfo()
         */

        self.setNowPlayingInfo()
        self.player = AVPlayer(url: url)

    }


    func setNowPlayingInfo()
    {
        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
        var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()

        let title = "title"
        let album = "album"
        let artworkData = Data()
        let image = UIImage(data: artworkData) ?? UIImage()
        let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: {  (_) -> UIImage in
            return image
        })

        nowPlayingInfo[MPMediaItemPropertyTitle] = title
        nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = album
        nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

        nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
    }

    @IBAction func startPlayingButtonPressed(_ sender: Any)
    {
        self.player.play()
    }

(ANCIENNE RÉPONSE IOS 8.2:} _

La réponse de Patrick est tout à fait juste.

Mais je vais écrire ce que je fais pour iOS 8.2:

J'ajoute l'info.plist De mon application, les modes d'arrière-plan requiscomme ci-dessous:

enter image description here

Et dans mon (AppDelegate.h} j'ajoute ces importations:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

Ensuite, dans mon AppDelegate.m j'ai écrit application didFinishLaunchingWithOptionsthis exactement comme ci-dessous:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

    return YES;
}

Maintenant, l'application continue à jouer de la musique même si l'écran est verrouillé :)

35
EFE

J'ai réussi à faire fonctionner l'audio en arrière-plan en ajoutant ce qui suit à ma applicationDidFinishLaunching

// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];    
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
11
atomoil

iOS 9 Swift

Tout ce dont vous avez besoin est d’ajouter ce qui suit à votre didFinishLaunchingWithOptions

do  {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    //TODO
}
3
Marcio Arantes

J'ai le même problème et j'ai trouvé une solution dans Apple Docs: https://developer.Apple.com/library/ios/qa/qa1668/_index.html

Q: Comment puis-je m'assurer que mon contenu multimédia continuera à jouer lorsque j'utilise AV Foundation lorsque mon application est en arrière-plan?

R: Vous devez déclarer que votre application lit du contenu audible en arrière-plan et attribuer une catégorie appropriée à votre session audio. Voir aussi Spécial Considérations pour les supports vidéo .

0
Andriy Savran