Mixto Tipo de vídeo contenido en cola en un AVQueuePlayer en el iPhone
-
25-09-2019 - |
Pregunta
Me gustaría empezar de disculpándose por este ridículamente largo post, pero me trató de proporcionar la mayor cantidad de código y datos como sea posible para que usted alude.
Estoy trabajando en un proyecto de vídeo, donde voy a necesitar la flexibilidad de la AVQueuePlayer (sobre todo la capacidad de escala y el diseño de la capa de vídeo libremente, así como la creación de mis controles personalizados). El problema es que tengo que ser capaz de mezclar el contenido de vídeo de diferentes tipos (en este caso progresiva descarga .mp4 y la transmisión HTTP .m3u8). Aquí es donde las cosas se ponen de moda.
En primer lugar algo de código para que te va:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *assetsArray = [NSArray arrayWithObjects:
[AVPlayerItem playerItemWithURL: [NSURL URLWithString: kTestPrerollURL]], // .mp4-file on server
[AVPlayerItem playerItemWithURL: [NSURL URLWithString: kTestVideoURL]], // .m3u8-file on server
[AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: @"2" ofType:@"m4v"]]], // local m4v-file
[AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: @"3" ofType:@"m4v"]]], // local m4v-file
nil];
// Add KVO observation on each player item to track when they are ready for playback
for(id playerItem in assetsArray) {
[playerItem addObserver: self forKeyPath:@"status" options: 0 context: NULL];
}
[self setPlayer: [AVQueuePlayer queuePlayerWithItems: assetsArray]];
[self setPlayerLayer: [AVPlayerLayer playerLayerWithPlayer: [self player]]];
[[self playerLayer] setFrame: [playerView bounds]];
// Additional layer customization...
[[playerView layer] addSublayer: [self playerLayer]];
[playerView setBackgroundColor: [UIColor clearColor]];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(playerItemDidReachEnd:)
name: AVPlayerItemDidPlayToEndTimeNotification
object: nil];
}
Y cuando el AVPlayerItem cambia de estado, se invoca este método:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
// A bunch of loggers...
if([(AVPlayerItem *)object status] == AVPlayerItemStatusReadyToPlay) {
CGSize movieSize = [[[player currentItem] asset] naturalSize];
CGRect playerRect = [playerView frame];
playerRect.size.height = playerRect.size.width * movieSize.height/movieSize.width + 7.0;
[playerView setFrame: playerRect];
[playerLayer setFrame: [playerView bounds]];
[player play];
}
}
Si los elige usuario pulse un botón "Siguiente", el reproductor salta al siguiente clip:
- (IBAction)next:(id)sender {
NSLog(@"------ USER SWITCHED TO NEXT ------");
AVPlayerItem *object = (AVPlayerItem *)[player currentItem];
[object removeObserver:self forKeyPath: @"status"];
[player advanceToNextItem];
}
Finalmente, cuando el AVPlayerItem llega al final, se invoca este método:
- (void)playerItemDidReachEnd:(NSNotification *)notification {
NSLog(@"------ PLAYER ITEM DID REACH END ------");
AVPlayerItem *object = (AVPlayerItem *)[notification object];
[object removeObserver:self forKeyPath: @"status"];
}
Ok, así que mi problema es que la mezcla de diferentes formatos (en este caso el M3U8-archivo) provoca un comportamiento cobarde.
Si se me carga el archivo M3U8-primero en la cola, se reproduce correctamente, pero si advanceToNextItem la aplicación se bloquea. informes NSZombieEnabled:
*** -[Not A Type retain]: message sent to deallocated instance 0x684dfe0
[Switching to process 67957]
y los espectáculos de la pila de llamadas de una liberación fuera de mis límites (myPlayer es el nombre del proyecto):
po [NSThread callStackSymbols]
2011-01-05 16:12:57.151 MyPlayer[67957:6303] *** __NSAutoreleaseNoPool(): Object 0x56a0580 of class _NSCallStackArray autoreleased with no pool in place - just leaking
<_NSCallStackArray 0x56a0580>(
0 MyPlayer 0x00002154 start + 0,
1 CoreFoundation 0x00e72f22 _CF_forwarding_prep_0 + 50,
2 CoreFoundation 0x00e140bc CFRetain + 92,
3 CFNetwork 0x014c436e _ZN21XConnectionEventQueueI12XLoaderEvent18XLoaderEventParamsE10pushEventsEP20XConnectionEventInfoIS0_S1_El + 120,
4 CFNetwork 0x014c4252 _ZN19URLConnectionLoader16pushEventsLockedEP20XConnectionEventInfoI12XLoaderEvent18XLoaderEventParamsEl + 120,
5 CFNetwork 0x014c41c7 _ZN19URLConnectionLoader10pushEventsEP20XConnectionEventInfoI12XLoaderEvent18XLoaderEventParamsEl + 57,
6 CFNetwork 0x015976b6 _ZN19URLConnectionClient25getRequestForTransmissionEhP14_CFURLResponsePK13_CFURLRequestPP9__CFError + 942,
7 CFNetwork 0x014c3030 _ZN19URLConnectionClient22_clientWillSendRequestEPK13_CFURLRequestP14_CFURLResponsePNS_26ClientConnectionEventQueueE + 230,
8 CFNetwork 0x01597789 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 141,
9 CFNetwork 0x014c2e3c _ZN19URLConnectionClient13processEventsEv + 100,
10 CFNetwork 0x014c2cb7 _ZN17MultiplexerSource7performEv + 251,
11 CoreFoundation 0x00ee301f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15,
12 CoreFoundation 0x00e4128b __CFRunLoopDoSources0 + 571,
13 CoreFoundation 0x00e40786 __CFRunLoopRun + 470,
14 CoreFoundation 0x00e40240 CFRunLoopRunSpecific + 208,
15 CoreFoundation 0x00e43504 CFRunLoopRun + 84,
16 CoreMedia 0x00cb39af FigThreadGlobalNetworkBufferingRunloop + 149,
17 CoreMedia 0x00cb624a figThreadMain + 308,
18 libSystem.B.dylib 0x9473885d _pthread_start + 345,
19 libSystem.B.dylib 0x947386e2 thread_start + 34
)
si el .m3u8-archivo se coloca en algún lugar después de la primera posición en la cola, aparece un estado de AVPlayerItemStatusFailed, y los saltos clip al siguiente clip de la cola.
Me da cuenta de esto podría estar relacionado con alguna de gestión de memoria, pero al mismo tiempo empezar a dudar de él. Sin embargo, es bastante evidente que estoy haciendo algo mal, por lo que cada sugerencia de una solución es más que bienvenido.
Solución
No se puede hacer esto - AVPlayer puede jugar cualquiera contenido HLS (M3U) o no escuchados, pero no una mezcla. Ver este para más detalles: https://devforums.apple.com/message/570406#570406