2011-01-05 5 views
0

私はこのばかばかしく長い記事をお詫びして始めたいと思いますが、できるだけ多くのコードとデータを参照して提供しようとしました。iPhone上のAVQueuePlayerでキューに入れられたコンテンツ

私はAVQueuePlayerの柔軟性(主に、ビデオレイヤーを自由にスケーリングしてレイアウトする機能とカスタマイズされたコントロールを作成する機能)が必要なビデオプロジェクトに取り組んでいます。問題は、私は異なるタイプのビデオコンテンツをミックスできる必要があることです(この場合、プログレッシブダウンロード.mp4とhttpストリーミング.m3u8)。ここで物事はファンキーになる。

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

をそしてAVPlayerItemがステータスを変更した場合、このメソッドが呼び出されます:あなたが軌道に乗るためにいくつかのコード

まず、ユーザは、「次へ」 - ボタンを押して選択した

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

場合次のクリップにスキップします。

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

最後に、AVPlayerItemが最後に到達すると、t彼のメソッドが呼び出されます。

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

オクラホマので、私の問題は、(この場合はM3U8ファイル)異なるフォーマットを混合して、いくつかのファンキーな行動を引き起こすことがあります。

m3u8ファイルを最初に読み込むと正しく再生されますが、もしadvanceToNextItemを実行すると、アプリケーションがクラッシュします。 NSZombieEnabledレポート:.m3u8-ファイルが最初にした後、どこかに配置されている場合

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 
) 

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

とコールスタックは私の範囲外の放出を示す(MyPlayerは、プロジェクトの名前です)キュー内の位置、私は状態AVPlayerItemStatusFailedを取得し、クリップはキュー内の次のクリップにスキップします。

私はこれがいくつかのメモリ管理に関連するかもしれないことを認識しますが、同時に私はそれを疑うようになります。しかし、私は何か間違っていることを明らかにしているので、解決策のすべての提案は歓迎する以上のものです。

+0

KVOを削除すると問題は解決しますか?もしそうなら、これはおそらくこれが本当にメモリ管理の問題であると示唆しているでしょう。ちょっとしたアイデア... – matt

+0

KVOを削除して、viewDidLoadの最後に[player play]を追加しても問題は解決しません。同じ動作 - クリップはスキップされています... – jollyCocoa

+0

この問題を修正しましたか?私もそれを打っている - m3u8ファイルは、それが最初の場合は正常に再生されますが、リストで2番目の場合はまったく再生されません。 –

答えて

3

これを行うことはできません - AVPlayerはHLSコンテンツ(M3U)または非ストリームのいずれかを再生できますが、ミックスは再生できません。 詳細を参照してください:https://devforums.apple.com/message/570406#570406

+0

参考になりました!それは私が最終的に真実であると仮定した何かに確証を与えました。どうもありがとう! – jollyCocoa

+0

もちろん、AVPlayersを適切なタイミングで作成/破棄した場合(つまり、ダウンロードされたストリーミングからストリーミングへの各変更の場合)、正しい取得が容易ではない –

関連する問題