He hecho un montón de investigación, tanto en Google y en StackOverflow. Todas las respuestas que he encontrado no funcionan en iOS 7. Empecé a escribir en los frescos de la aplicación en iOS 7 SDK con Xcode 5.

Todo lo que estoy tratando de hacer es reproducir el audio en la aplicación desde un archivo almacenado en la aplicación de paquete (no desde la biblioteca de Música). Quiero tener audio que se reproduzca en segundo plano y controlada cuando la pantalla está bloqueada (además de Centro de Control).

Me puse el APPNAME-Info.plist clave, UIBackgroundModes, a de audio. No es la manipulación de las cosas en la app delegado; todo se hace dentro de la ViewController

@interface ViewController : UIViewController <AVAudioPlayerDelegate>

Dentro de la implementación del viewDidAppear: método que yo llamo «super» y, a continuación, el siguiente código:

//Once the view has loaded then we can register to begin receiving controls and we can become the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

En mi implementación del viewWillDisappear: método, tengo el siguiente código:

//End receiving events
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];

También he implementado el canBecomeFirstResponder método, que devuelve . A continuación, he implementado el remoteControlReceivedWithEvent: método:

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    //If it is a remote control event handle it correctly
    if (event.type == UIEventTypeRemoteControl) {
        if (event.subtype == UIEventSubtypeRemoteControlPlay) {
            [self playPauseAudio:self];
        } else if (event.subtype == UIEventSubtypeRemoteControlPause) {
            [self playPauseAudio:self];
        } else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
            [self playPauseAudio:self];
        }
    }
}

Lo que me confunde es que esta misma instalación estaba trabajando bien en iOS 6. En iOS 7, no funciona. Solía ser tan fácil en iOS 6. Algo cambió en el SDK de iOS 7. Lo que me estoy perdiendo?

InformationsquelleAutor codejunkie | 2013-09-24

5 Comentarios

  1. 16

    Me las arreglé para resolver esto, y para guardar el pelo tirando por otra pobre alma que aquí va:

    En primer lugar, asegúrese de que su Información.plist correctamente las listas de audio como un modo de fondo.

    (Si no sabes de qué estoy hablando seleccione YOURAPPNAME-Info.plist que seleccione. Haga clic en oin el signo más y agregar una nueva clave llamada UIBackgroundModes y expandirla. Agregue un valor llamado audio.)

    Necesitará una referencia a lo que la reproducción del objeto es la creación de audio. Ya que estoy solo para la reproducción de audio y AVplayer no estaba cumpliendo con el audio de fondo, el uso de esta en la vista del controlador de cabecera:

    @property (nonatomic, retain) MPMoviePlayerController *audioPlayer;

    En la aplicación, haga lo siguiente:

     [super viewDidAppear:animated];
    
        //Once the view has loaded then we can register to begin recieving controls and we can become the first responder
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        [self becomeFirstResponder];

    y

    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
    
        //End recieving events
        [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
        [self resignFirstResponder];

    agregar dos métodos

    //Make sure we can recieve remote control events
    - (BOOL)canBecomeFirstResponder {
        return YES;
    }
    
    - (void) registerForAudioObjectNotifications {
    
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    
        [notificationCenter addObserver: self
                               selector: @selector (handlePlaybackStateChanged:)
                                   name: MixerHostAudioObjectPlaybackStateDidChangeNotification
                                 object: audioObject];
    }

    ahora TODO el código importante – esto permite su aplicación para controlar el audio desde el «centro de control» y desde la pantalla de bloqueo:

    - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
    
        if (receivedEvent.type == UIEventTypeRemoteControl) {
    
            switch (receivedEvent.subtype) {
    
                case UIEventSubtypeRemoteControlTogglePlayPause:
                    [self playOrStop: nil];
                    break;
    
                default:
                    break;
            }
        }
    }

    usted puede agregar muchos tipos de tipos de Eventos aquí y llamar a cualquier método.

    Típico de eventos:

     UIEventSubtypeRemoteControlPlay                 = 100,  //Parent EVENT
    
    //All below are sub events and you can catch them using switch or If /else.
        UIEventSubtypeRemoteControlPause                = 101,
        UIEventSubtypeRemoteControlStop                 = 102,
        UIEventSubtypeRemoteControlTogglePlayPause      = 103,
        UIEventSubtypeRemoteControlNextTrack            = 104,
        UIEventSubtypeRemoteControlPreviousTrack        = 105,
        UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
        UIEventSubtypeRemoteControlEndSeekingBackward   = 107,
        UIEventSubtypeRemoteControlBeginSeekingForward  = 108,
        UIEventSubtypeRemoteControlEndSeekingForward    = 109,

    Para Depurar, se puede utilizar:

     MPMoviePlayerController *mp1= (MPMoviePlayerController *)[notification object];
        NSLog(@"Movie State is: %d",[mp1 playbackState]);
    
        switch ([mp1 playbackState]) {
            case 0:
                NSLog(@"******* video has stopped");
                break;
            case 1:
                NSLog(@"******* video is playing after being paused or moved.");
                           break;
            case 2:
                NSLog(@"******* video is paused");
                    break;
            case 3:
                NSLog(@"******* video was interrupted");
                break;
            case 4:
                NSLog(@"******* video is seeking forward");
                         break;
            case 5:
                NSLog(@"******* video is seeking Backwards");
                break;
            default:
                break;

    y eso es todo – espero que ayude alguien por ahí! – este es el trabajo perfecto en iOS 7 y iOS 6 con Guión gráfico de la aplicación, así como controlar el uso de Auriculares y de todo el nuevo centro de control también.

    • Por desgracia, esto todavía no funciona para mí desde el centro de control. Este es exactamente el mismo código que me fue fructífera utilizando en iOS6, pero con iOS7 algo se rompió. De hecho, he visto también que otras aplicaciones tales como StereoMood y 8Tracks tienen el mismo problema.
    • has probado en iOS 7.0.3 obras perfecta para mí.
    • Tuve la misma experiencia como super hizo. En iOS 7.0.3 es todavía el mismo. Hice la mayoría de los pasos como se indican con excepción de que mi respondedor código es en el AppDelegate y no tengo un objeto de audio. Centro de Control simplemente no llama remoteControlReceivedWithEvent:. Tenga en cuenta que mi código funciona para todos los pre-iOS7 ocasiones y todavía trabaja para el adaptador de control remoto. A ver mi pregunta aquí, por favor: stackoverflow.com/questions/19686704/…
    • En realidad se comenzó a trabajar de nuevo después de un reinicio de mi iPhone. Ahora en iOS 7.0.3 sigue funcionando sin problemas. Eso es realmente algo extraño con iOS7.
    • ¿Qué MixerHostAudioObjectPlaybackStatedidchangenotification tiene que ver con la recepción de eliminar eventos?
  2. 7

    Al parecer el problema estaba en el lado de Apple como la actualización de iOS 7.0.3 corrige este problema. Además de lo que Alex notó sobre UIEventSubtype cambios en el código que funcionaba en iOS6 ahora funciona en iOS7.

    En aras de la exhaustividad, aquí está mi código correspondiente que está trabajando en iOS6 y iOS7 – después de que el udpate a 7.0.3. También se incluye AVFoundation.marco y MediaPlayer.marco de referencia en el proyecto de construcción de las Fases -> Link binario con las bibliotecas. Ningún código para esta aplicación delegado.

    En viewcontroller .h archivo:

    #import <AVFoundation/AVFoundation.h>
    #import <MediaPlayer/MediaPlayer.h>
    
    @interface NewsDetailViewController : UIViewController <UIWebViewDelegate, AVAudioSessionDelegate>
    @property (nonatomic) MPMoviePlayerController *audioPlayer;

    En viewcontroller .m de archivo:

    - (void)viewDidLoad
    {
    [super viewDidLoad];
    self.audioPlayer = [[MPMoviePlayerController alloc] initWithContentURL:audioUrl];
    [self.audioPlayer prepareToPlay];
    [self.audioPlayer.view setFrame:CGRectMake(0, 0, self.audioView.frame.size.width,     42)];
    self.audioPlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    [self.audioView addSubview:self.audioPlayer.view];
    [self.audioPlayer play];
    NSError *setCategoryError = nil;
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive:YES error:&activationError];
    [[AVAudioSession sharedInstance] setDelegate:self];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
    }
    - (BOOL)canBecomeFirstResponder {
    return YES;
    }
    - (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    }
    - (void)viewWillDisappear:(BOOL)animated {
    [self.audioPlayer stop];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
    }
    - (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
    if (receivedEvent.type == UIEventTypeRemoteControl) {
    switch (receivedEvent.subtype) {
    case UIEventSubtypeRemoteControlPlay:
    [self.audioPlayer play];
    break;
    case UIEventSubtypeRemoteControlPause:
    [self.audioPlayer pause];
    break;
    case UIEventSubtypeRemoteControlTogglePlayPause:
    if (self.audioPlayer.playbackState == MPMoviePlaybackStatePlaying) {
    [self.audioPlayer pause];
    }
    else {
    [self.audioPlayer play];
    }
    break;
    default:
    break;
    }
    }
    }
  3. 6

    Si quieres jugar de audio en segundo plano en el iphone y el simulador también entonces usted necesita para escribir este código en plist y en primer lugar, asegúrese de que su Información.plist correctamente las listas de audio como un modo de fondo.

    (Si no sabes de qué estoy hablando seleccione YOURAPPNAME-Info.plist que seleccione. Haga clic en el signo más y escriba una clave de UIBackgroundModes y entrar. Agregar un valor que se denomina «Aplicación reproduce audio»(para el simulador) o «Aplicación reproduce audio o flujos de audio/vídeo mediante AirPlay»(Para iphone).)

    iOS 7 SDK de la no observancia de audio de fondo

    en AppDelegate.m

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
    __block UIBackgroundTaskIdentifier task = 0;
    task=[application beginBackgroundTaskWithExpirationHandler:^{
    NSLog(@"Expiration handler called %f",[application backgroundTimeRemaining]);
    [application endBackgroundTask:task];
    task=UIBackgroundTaskInvalid;
    }];
    }

    Añadir estas dos marco de su proyecto y alguna línea de código en ViewController.h

    #import <AVFoundation/AVFoundation.h>
    #import <MediaPlayer/MediaPlayer.h>
    @interface ViewController : UIViewController <UIWebViewDelegate, AVAudioSessionDelegate>
    @property (nonatomic) MPMoviePlayerController *audioPlayer;

    Recordar que estos marcos refrences debe ser añadido en el proyecto.

    A continuación, en Viewcontrller.m

    - (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    }
    - (void)viewWillDisappear:(BOOL)animated {
    [self.audioPlayer stop];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
    }
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    //Do any additional setup after loading the view, typically from a nib.
    NSURL *audioUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"songName" ofType:@"mp3"]];
    self.audioPlayer = [[MPMoviePlayerController alloc] initWithContentURL:audioUrl];
    [self.audioPlayer prepareToPlay];
    [self.audioPlayer.view setFrame:CGRectMake(0, 0, self.view.frame.size.width-100,     42)];
    self.audioPlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    [self.view addSubview:self.audioPlayer.view];
    [self.audioPlayer play];
    //for run application in background
    NSError *setCategoryError = nil;
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive:YES error:&activationError];
    [[AVAudioSession sharedInstance] setDelegate:self];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
    }

    Espero que le ayudará a jugar de audio en segundo plano en el iphone y el simulador así.

    • la modificación de appdelegate no es una buena práctica de código y debemos tratar de mantenerse alejado de appdelegate como este se basa en el sistema operativo cuando el app es la primera carga y se lleva el control de la aplicación de controladores de más leer aquí: hollance.com/2012/02/dont-abuse-the-app-delegate
    • funciona perfectamente en segundo plano,,, ¿qué pasa cuando la vista se cambia?
    • he pop de nuevo otro punto de vista, pero quiero jugar mismo de audio de la vista anterior
  4. 4

    Una cosa a tener en cuenta de que es diferente de iOS6 a iOS7 con control remoto de eventos es que en iOS6 reproducir/pausa eventos de vino como UIEventSubtype:
    UIEventSubtypeRemoteControlTogglePlayPause

    Y en iOS7 vienen dos subtipos:

    UIEventSubtypeRemoteControlPause

    UIEventSubtypeRemoteControlPlay

  5. 0

    Ya que yo también estoy interesado en la búsqueda de esta solución voy a añadir algo más de información a partir de mi lado.

    Estoy experimentando el mismo problema, pero todavía la documentación de Apple no ha cambiado con respecto a control remoto de gestión de eventos.

    Traté de mover algunas cosas y sucedió algo interesante.

    Que originalmente tenía el control remoto de gestión de eventos en mi TabBar controlador. Ahora que me mudé todo en el reproductor de controlador de vista, puedo ver que me puede volver a controlar la reproducción de música con mis auriculares, pero no de los botones en el panel de control de nuevo iOS7 (los que vienen de la parte inferior de la pantalla).

    Esto es bastante raro.

    Con el fin de resolver el problema, vamos a tratar de enriquecer el hilo con nuestra prueba.

    • Actualmente estoy probando y encontrar trabajo en torno al uso del MPMPlayerViewController y registrarse con su objeto de notificación y obtención de ese estado se actualizará una vez que tengo todos los que trabajan.
    • No estoy utilizando una MPPlayer, así que no puedo registrar para aquellos notificación. Es una locura porque he resuelto el problema sólo se mueve todo en el AppDelegate, pero ahora ya no funciona.

Dejar respuesta

Please enter your comment!
Please enter your name here