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이 끝에 도달하면

- (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]를 추가해도 문제가 해결되지 않습니다. 동일한 동작 - 클립이 건너 뛰고 beeing ... – jollyCocoa

+0

혹시이 문제를 해결 했습니까? 나는 그것도 타격을 가하고있다. m3u8 파일은 처음이라면 잘 재생되지만 목록에 2 번째라면 전혀 재생되지 않는다. –

답변

3

당신은 할 수 없습니다 - AVPlayer는 HLS 콘텐츠 (M3U) 또는 비 스트리밍 중 하나를 재생할 수 있지만 믹스는 재생할 수 없습니다. 자세한 내용은 다음을 참조하십시오. https://devforums.apple.com/message/570406#570406

+0

감사합니다. 나는 마침내 진실이라고 생각한 것을 확인해주었습니다. 고마워! – jollyCocoa

+0

물론 AVPlayers를 적시에 (즉 다운로드 한/다운로드 한 각 변경 사항에 대해) 만들거나/파괴하는 경우이 기능을 사용할 수 있지만 올바르게 진행하기는 쉽지 않습니다. –