2013-12-22 3 views
1

비디오 및 오디오 컴포지션의 비디오를 표시하려고합니다. 그러나 비디오 상태가 AVPlayerStatusReadyToPlay에 도달하지 못하면 문제가있는 것 같습니다.오디오 및 비디오가 포함 된 AVMutableComposition의 AVPlayer가 재생되지 않습니다.

동영상 애셋 또는 오디오 애셋을 플레이어 항목에 직접 포함하면 작동합니다. 따라서 자산에 문제가 없다는 것을 알고 있습니다. 내 경험에서

 - (void) loadPlayer { 
      NSURL *videoURL = **; 
      AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil]; 

      NSURL *audioURL = **; 
      AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:audioURL options:nil]; 


      NSArray *keys = [NSArray arrayWithObject:@"duration"]; 
      [videoAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^() { 

       NSError *error = nil; 
       AVKeyValueStatus durationStatus = [videoAsset statusOfValueForKey:@"duration" error:&error]; 

       switch (durationStatus) { 
        case AVKeyValueStatusLoaded:; 
         _videoDuration = videoAsset.duration; 
         if (_audioDuration.flags == kCMTimeFlags_Valid) { 
          [self loadPlayWithVideoAsset:videoAsset withDuration:_videoDuration andAudioAsset:audioAsset withDuration:_audioDuration]; 
         } 
         break; 
       } 
      }]; 

      [audioAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^() { 

       NSError *error = nil; 
       AVKeyValueStatus durationStatus = [audioAsset statusOfValueForKey:@"duration" error:&error]; 

       switch (durationStatus) { 
        case AVKeyValueStatusLoaded:; 
         _audioDuration = audioAsset.duration; 
         if (_videoDuration.flags == kCMTimeFlags_Valid) { 
          [self loadPlayWithVideoAsset:videoAsset withDuration:_videoDuration andAudioAsset:audioAsset withDuration:_audioDuration]; 
         } 
         break; 
       } 
      }]; 
     } 

     - (void) loadPlayWithVideoAsset:(AVURLAsset *)videoAsset withDuration:(CMTime)videoDuration andAudioAsset:(AVURLAsset *)audioAsset withDuration:(CMTime)audioDuration { 


     AVMutableComposition *composition = [AVMutableComposition composition]; 

     //Video 
     AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject]; 
     NSError *videoError = nil; 
     if (![compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,videoDuration) 
              ofTrack:videoTrack 
              atTime:kCMTimeZero 
               error:&videoError]) { 
      NSLog(@"videoError: %@",videoError); 
     } 



     //Audio 
     AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
     AVAssetTrack *audioTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] lastObject]; 
     NSError *audioError = nil; 
     if (![compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,audioDuration) 
              ofTrack:audioTrack 
              atTime:kCMTimeZero 
               error:&audioError]) { 
      NSLog(@"audioError: %@",audioError); 
     } 


     NSInteger compare = CMTimeCompare(videoDuration, audioDuration); 

     if (compare == 1) { 
      //The video is larger 
      CMTime timeDiff = CMTimeSubtract(videoDuration, audioDuration); 
      [compositionAudioTrack insertEmptyTimeRange:CMTimeRangeMake(audioDuration, timeDiff)]; 
     } 
     else { 
      CMTime timeDiff = CMTimeSubtract(audioDuration, videoDuration); 
      [compositionVideoTrack insertEmptyTimeRange:CMTimeRangeMake(videoDuration, timeDiff)]; 
     } 
     AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:composition]; 
     self.mPlayer = [AVPlayer playerWithPlayerItem:playerItem]; 
     self.mPlaybackView = [[AVPlayerPlaybackView alloc] initWithFrame:CGRectZero]; 
     [self.view addSubview:self.mPlaybackView]; 
     [self.mPlayer addObserver:self forKeyPath:@"status" options:0 context:AVPlayerPlaybackViewControllerStatusObservationContext]; 
} 
- (void)observeValueForKeyPath:(NSString*) path ofObject:(id)object change:(NSDictionary*)change context:(void*)context 
{ 
    if (self.mPlayer.status == AVPlayerStatusReadyToPlay) { 
     [self.mPlaybackView setPlayer:self.mPlayer]; 
     isReadyToPlay = YES; 
     _playVideoBtn.hidden = NO; 
    } 
} 
- (void) playVideo { 
    if (YES || isReadyToPlay) { 
     [self.mPlayer play]; 
    } 
} 
+0

모든 뉴스? 현재 같은 문제가 발생합니다. ( –

답변

0

는 AVPlayer를 자원/비디오 응용 프로그램과 함께 번들로 제공되는 경우에만 AVMutableComposition 작동 :

내 코드입니다. 비디오 자원이 네트워크에있는 경우 AVPlayer는 AVPlayerItem 및 AVPlayer가 "Ready to Play"로보고 한 상태에도 불구하고 AVMUtableComposition으로 재생하지 않습니다.