2012-05-19 10 views
6

के दौरान AVPlayerItem की वीडियो कॉम्पोजिशन प्रॉपर्टी (AVMutableVideoComposition) बदलना मैं प्लेबैक के दौरान एक वीडियो संरचना के लेआउट (यानी इसके घटक फ्रेम 'ट्रांसफॉर्म) को बदलने की कोशिश कर रहा हूं। ऐसा लगता है कि कभी-कभी यह काम करता है, और वीडियो संरचना ट्रांसफॉर्म के नए सेट में सहजता से बदलती है, लेकिन दूसरी बार यह केवल स्थिर हो जाती है और वर्तमान परिवर्तनों के साथ रहता है। AVPlayer इंस्टेंस पर कोई स्टेटस कोड परिवर्तन नहीं है, और प्लेयर या प्लेयर आइटम पर कोई त्रुटि नहीं है।प्लेबैक

क्या किसी ने इससे पहले अनुभव किया है? यह क्यों हो रहा है, या इसके आसपास कैसे जाना है, इस पर कोई सुझाव दिया जाएगा।

कुछ कोड नीचे दिखाया गया है। महत्वपूर्ण बिट 'playerItem.videoComposition = VideoComposition' है, जो यहां वीडियो को टैप करने (परीक्षण उद्देश्यों के लिए) ट्रिगर किया गया है।

इस समस्या का एक और समाधान अलग-अलग परतों पर वीडियो प्रदर्शित करना होगा, लेकिन यह जरूरी है कि वीडियो सिंक हो जाएं ताकि एक रचना इसे प्राप्त करने का एकमात्र तरीका प्रतीत हो।

@implementation VideoView 
{ 
    CGSize _videoSize; 
    CMTimeRange _videoFullRange; 

    AVMutableCompositionTrack * _compositionTrackVideoA; 
    AVMutableCompositionTrack * _compositionTrackVideoB; 
} 

+ (Class)layerClass 
{ 
    return [AVPlayerLayer class]; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     NSString * videoAPath = [[NSBundle mainBundle] pathForResource:@"cam09v2" ofType:@"mp4"]; 
     NSString * videoBPath = [[NSBundle mainBundle] pathForResource:@"cam10v2_b" ofType:@"mp4"]; 
     AVURLAsset * videoAAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:videoAPath] options:nil]; 
     AVURLAsset * videoBAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:videoBPath] options:nil]; 

     AVAssetTrack * videoATrack = [[videoAAsset tracksWithMediaType:AVMediaTypeVideo] lastObject]; 
     AVAssetTrack * videoBTrack = [[videoBAsset tracksWithMediaType:AVMediaTypeVideo] lastObject]; 
     AVAssetTrack * audioTrack = [[videoAAsset tracksWithMediaType:AVMediaTypeAudio] lastObject]; 

     _videoSize = [videoATrack naturalSize]; 
     CMTime videoDuration = videoAAsset.duration; 
     _videoFullRange = CMTimeRangeMake(kCMTimeZero, videoDuration); 

     AVMutableComposition *composition = [AVMutableComposition composition]; 
     AVMutableCompositionTrack * compositionTrackVideoA = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     AVMutableCompositionTrack * compositionTrackVideoB = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     AVMutableCompositionTrack * compositionTrackAudio = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

     compositionTrackVideoA.preferredTransform = videoATrack.preferredTransform; 

     NSError * error = nil; 
     if (! [compositionTrackVideoA insertTimeRange:_videoFullRange ofTrack:videoATrack atTime:kCMTimeZero error:&error]) 
      NSLog(@"%@", error); 

     if (! [compositionTrackVideoB insertTimeRange:_videoFullRange ofTrack:videoBTrack atTime:kCMTimeZero error:&error]) 
      NSLog(@"%@", error); 

     if (! [compositionTrackAudio insertTimeRange:_videoFullRange ofTrack:audioTrack atTime:kCMTimeZero error:&error]) 
      NSLog(@"%@", error); 

     _compositionTrackVideoA = [compositionTrackVideoA copy]; 
     _compositionTrackVideoB = [compositionTrackVideoB copy]; 

     AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:composition]; 

     AVPlayer * player = [AVPlayer playerWithPlayerItem:playerItem]; 

     [(AVPlayerLayer *)self.layer setPlayer:player]; 

     [player play]; 

     [player addObserver:self forKeyPath:@"status" options:0 context:0]; 

     [self updateCompositionForPlayerItem:playerItem]; 

     UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)]; 
     [self addGestureRecognizer:tapGesture]; 
    } 
    return self; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if ([keyPath isEqualToString:@"status"]) 
     NSLog(@"STATUS %d", ((AVPlayer *)object).status); 
} 

- (void)updateCompositionForPlayerItem:(AVPlayerItem *)playerItem 
{ 

    AVMutableVideoComposition * videoComposition = [AVMutableVideoComposition videoComposition]; 

    AVMutableVideoCompositionInstruction *videoInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    videoInstruction.enablePostProcessing = NO; 
    videoInstruction.timeRange = _videoFullRange; 

    AVMutableVideoCompositionLayerInstruction * layerInstructionA = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:_compositionTrackVideoA]; 
    CGAffineTransform transformA = CGAffineTransformMakeScale(0.5, 0.5); 
    [layerInstructionA setTransform:transformA atTime:kCMTimeZero]; 
    AVMutableVideoCompositionLayerInstruction * layerInstructionB = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:_compositionTrackVideoB]; 
    CGAffineTransform transformB = CGAffineTransformMakeScale(0.5, 0.5); 
    static int i = 0; 
    transformB = CGAffineTransformTranslate(transformB, (i++ % 2 == 0) ? _videoSize.width : 0, _videoSize.height); 
    [layerInstructionB setTransform:transformB atTime:kCMTimeZero]; 

    videoInstruction.layerInstructions = [NSArray arrayWithObjects:layerInstructionA, layerInstructionB, nil]; 

    videoComposition.instructions = [NSArray arrayWithObject:videoInstruction]; 

    videoComposition.frameDuration = CMTimeMake(1, 30); // 30 fps 
    videoComposition.renderSize = _videoSize; 

    playerItem.videoComposition = videoComposition; 

} 

- (void)didTap:(UITapGestureRecognizer *)tapGesture 
{ 
    [self updateCompositionForPlayerItem:((AVPlayerLayer *)self.layer).player.currentItem]; 
} 

@end 

उत्तर

1

आप समय जहां आप इसे बदल सकते हैं और एक नया वीडियो संरचना के साथ खिलाड़ी आइटम की जगह और समय जहां खेल रहे stoped से नए खिलाड़ी आइटम के साथ फिर से खिलाड़ी शुरू करना चाहते हैं बचा सकता है।

संबंधित मुद्दे