2011-03-17 8 views
7

Tengo un controlador de vista que usa AVPlayer. este controlador de vista puede cargar un controlador de vista modal donde el usuario puede grabar audio usando AVAudioRecorder.SDK de iPhone: AVAudioRecorder no grabará después de llamar [AVPlayer play]

esto es lo que sucede:

si el usuario juega la composición en el controlador de puño con [AVPlayer juego] la AVAudioRecorder no grabará en el controlador de vista modal. no hay errores, pero la hora actual devuelta por AVAudioRecorder es 0.0;

si el usuario cierra el cuadro de diálogo modal y lo vuelve a cargar. AVAudioRecorder funciona bien.

Esto se puede repetir una y otra AVAudioRecorder no funciona la primera vez que se invoca después de un [juego AVPlayer] llaman

he estado luchando con esto durante días y sólo han reorganizado mi código relacionado tanto AVPlayer y AVAudioRecorder y todavía está actuando raro.

Cualquier ayuda o puntero se aprecia mucho

Gracias de antemano

Jean-Pierre

+0

hi probarlo por la solución que trabajó para mí http://stackoverflow.com/questions/4148123/avaudiorecorder-wont-record-if-movie-was-previously-recorded-played –

Respuesta

0

no debería ser [AVAudioRecorder record]; en lugar de play?

3

¿Cómo está configurando la categoría AVAudioSession, es decir, reproducir o grabar? Pruebe algo como

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 
+1

Hola Don. Sí, hago esto Esto está en las manos de Apple ahora. Parece que podría ser un error en su código. Gracias por la respuesta. Actualizaré esta publicación cuando obtenga más información. –

+0

Eso está funcionando bien para mí – yogs

1

He estado teniendo el mismo problema. Uso AVPlayer para reproducir composiciones (grabaciones anteriores para las que utilicé AVAudioRecord). Sin embargo, descubrí que una vez que he usado AVPlayer ya no puedo usar AVAudioRecorder. Después de algunas búsquedas, descubrí que siempre que AVPlayer se haya instanciado en la memoria y se haya reproducido al menos una vez (lo cual es usualmente lo que se hace inmediatamente después de crear una instancia) AVAudioRecorder no grabará. Sin embargo, una vez que AVPlayer se desasigna, AVAudioRecorder quedará libre para grabar nuevamente. Parece que AVPlayer se aferra a algún tipo de conexión que AVAudioRecorder necesita, y es codicioso ... no lo dejará ir hasta que lo saques de sus frías manos muertas.

Esta es la solución que he encontrado. Algunas personas afirman que la creación de instancias de AVPlayer toma demasiado tiempo para seguir desglosando y configurando una copia de seguridad. Sin embargo, eso no es verdad. La creación de instancias de AVPlayer es bastante trivial. Así que también está creando instancias de AVPlayerItem. Lo que no es trivial está cargando AVAsset (o cualquiera de sus subclases). Realmente solo quieres hacer eso una vez. clave que es utilizar esta secuencia:

  1. carga hasta AVAsset (por ejemplo, si va a cargar desde un archivo, utilice AVURLAsset directa o añadirlo a una AVMutableComposition y usar eso) y tener una referencia a él. No lo dejes ir hasta que hayas terminado con eso. Cargarlo es lo que lleva todo el tiempo.
  2. Una vez que esté listo para jugar: cree una instancia de AVPlayerItem con su activo, luego AVPlayer con AVPlayerItem y juegue. No mantenga una referencia a AVPlayerItem, AVPlayer lo mantendrá referenciado y no podrá reutilizarlo con otro reproductor de todos modos.
  3. Una vez que haya terminado de jugar, destruye inmediatamente AVPlayer ... libéralo, establece su var a nil, lo que sea que necesites hacer.**
  4. Ahora puede grabar. AVPlayer no existe, por lo que AVAudioRecorder es libre de hacer su trabajo.
  5. Cuando esté listo para volver a jugar, vuelva a crear una instancia de AVPlayerItem con el activo que ya ha cargado & AVPlayer. Nuevamente, esto es trivial. El activo ya se ha cargado, por lo que no debería haber un retraso.

** Tenga en cuenta que la destrucción de AVPlayer puede requerir algo más que simplemente liberarla y establecer su var en cero. Lo más probable es que también haya agregado un observador de tiempo periódico para realizar un seguimiento del progreso de la reproducción. Cuando haces esto, recibes de vuelta un objeto opaco al que debes aferrarte. Si no quita este elemento del reproductor Y lo suelta/establece en cero, AVPlayer no se destrabará. Parece que Apple crea un ciclo de retención intencional que debe romper manualmente. Así que antes de destruir AVPlayer lo que necesita (ejemplo):

[_player removeTimeObserver:_playerObserver]; 
[_playerObserver release]; //Only if you're not using ARC 
_playerObserver = nil; 

Como nota al margen, es posible que también haya configurado NSNotifications (utilizo uno para determinar cuando el jugador ha completado de juego) no lo hace ... olvida eliminar esos también.

+0

Gracias por su pista para destruir AVPlayer. Hubiera tomado mucho más tiempo si no hubiera leído esto. – chritaso

8

He estado teniendo el mismo problema también, y esta es la solución que encontré.

Al grabar, escribir este código de línea después de AVAudioRecord se inicializa:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:NULL];

luego llamar a record método.

+0

¡Este realmente ayuda! Configure AVAudioSessionCategoryRecord al grabar y AVAudioSessionCategoryPlayback al reproducir. También hay AVAudioSessionCategoryPlayAndRecord que podría funcionar mejor para los casos donde necesite grabar y reproducir simultáneamente. –

0

Tuve el mismo problema: AVAudioRecorder no comenzó a grabar. Mi ejemplo es un poco diferente: tengo una aplicación basada en tabbar con varios AVAudioPlayers en las diferentes vistas. Por el bien del ejemplo, digamos que la primera vista cargada tiene 3 AVAudioPlayers, mientras que la segunda vista tiene un AVAudioPlayer y un AVAudioRecorder. Todos se inician en el método viewDidLoad.

La grabadora no funcionaba en la segunda vista. Cuando presioné mi botón de grabación, la vista se sacudió ligeramente y la grabación no comenzó. Extrañamente, el simulador funcionó bien y no mostró los mismos síntomas ... (¿alguien tiene una idea de por qué?)

Después de investigar y leer este hilo me he dado cuenta de que no he configurado los reproductores en la primera vista a cero, así que supongo que todavía estaban en la memoria evitando que la grabadora se inicie. Una vez que los establecí en nil en el método viewDidDisappear, estaba funcionando bien de nuevo.

aquí es lo que me ayudó:

-(void)viewDidDisappear:(BOOL)animated { 
    firstPlayer = nil; 
    secondPlayer = nil; 
    thirdPlayer = nil; 
} 

ViewDidUnload no ayudó porque la vista, y por tanto los variablbes en la clase en sí no fueron descargados al cambiar de vista.

Espero que esto también sea útil para otros.

1

Si necesita utilizar AVPlayer y AVAudioRecorder al mismo tiempo, hacer lo siguiente:

  1. programar una categoría de audio a "reproducir y grabar" (como se describió anteriormente, o con función de sesión de audio basado en lenguaje C)
  2. " El método "record" debe invocarse después de la invocación del método "play" con cierto retraso. (Configuro 0.5 segundos)

Si no lo proporciona, la reproducción comenzará pero la grabación no se iniciará.

0

@La explicación de Aaron Hayman es precisa, pero la solución para mí fue muy simple. Simplemente implemente el método didFinishPlaying del delegado del jugador y libere al jugador allí.

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ 
    self.playerWord = nil; 
} 
Cuestiones relacionadas