Frage

Ich möchte von starten, indem Sie für dieses lächerlich langen Pfosten zu entschuldigen, aber ich versuchte, so viel Code und Daten wie möglich zur Verfügung zu stellen für Sie zu verweisen.

Ich arbeite an einem Video-Projekt, bei dem ich die Flexibilität des AVQueuePlayer benötigt (vor allem der Fähigkeit, Größe und Layout die Videoschicht frei, sowie die Schaffung meine maßgeschneiderten Kontrollen). Das Problem ist, ich brauche Video-Inhalte von verschiedenen Typen mischen zu können (in diesem Fall der progressiven Download .mp4 und HTTP-Streaming .m3u8). Hier ist, wo die Dinge flippig erhalten.

Zuerst einige Code, um Sie gehen:

- (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];
}

Und wenn die AVPlayerItem Status ändert, wird diese Methode aufgerufen:

- (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];
   }
}

Wenn der Benutzer wählt einen "Next" -Button zu drücken, werden die Spieler springt zum nächsten Clip:

- (IBAction)next:(id)sender {
   NSLog(@"------ USER SWITCHED TO NEXT ------");
   AVPlayerItem *object = (AVPlayerItem *)[player currentItem];
   [object removeObserver:self forKeyPath: @"status"];
   [player advanceToNextItem];
}

Wenn schließlich die AVPlayerItem das Ende erreicht hat, wird diese Methode aufgerufen:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
   NSLog(@"------ PLAYER ITEM DID REACH END ------");
   AVPlayerItem *object = (AVPlayerItem *)[notification object];
   [object removeObserver:self forKeyPath: @"status"];
}

Ok, also mein Problem ist, dass unterschiedliche Formate Mischen (in diesem Fall der m3u8-Datei) verursacht einige flippigen Verhalten.

Wenn ich die m3u8-Datei zuerst in der Warteschlange geladen werden, spielt es richtig, aber wenn ich advanceToNextItem die App abstürzt. NSZombieEnabled Berichte:

*** -[Not A Type retain]: message sent to deallocated instance 0x684dfe0
[Switching to process 67957]

Und die Call-Stack zeigt eine Freigabe aus meinen Grenzen (MyPlayer ist der Name des Projektes):

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
)

, wenn die .m3u8-Datei irgendwo nach der ersten Position in der Warteschlange gestellt wird, erhalte ich eine Status AVPlayerItemStatusFailed, und der Clip springt zum nächsten Clip in der Warteschlange.

Ich weiß, das bis zu einem gewissen Speicherverwaltung in Zusammenhang stehen könnte, aber zur gleichen Zeit beginne ich es zu zweifeln. Es ist jedoch ganz offensichtlich, dass ich etwas falsch mache, so dass jeder Vorschlag einer Lösung mehr als willkommen ist.

War es hilfreich?

Lösung

Sie können dies nicht tun - AVPlayer kann entweder spielen HLS-Gehalt (M3U) oder nicht gestreamt, aber keinen Mix. Sehen Sie diese Details: https://devforums.apple.com/message/570406#570406

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top