2016-03-21 7 views
1

Ich erstelle eine Anwendung, die sich mit dem Video beschäftigt, das im lokalen Verzeichnis der App existiert. Jetzt möchte ich ein Wasserzeichen darin einfügen. Aber es zeigt einen Fehler: -Fehler beim Hinzufügen eines Wasserzeichens in einem Video

{NSLocalizedDescription = Kann nicht dekodieren NSLocalizedFailureReason = Die Mediendaten nicht entschlüsselt werden können. Es ist möglicherweise beschädigt.}

Bitte helfen Sie mir für das Erhalten dieses Problem

-(void)displayWatermarkInVideo 
{ 
NSString *path = [[NSBundle mainBundle]pathForResource:@"Video_20160102191557356_by_videoshow" ofType:@"mp4"]; 
NSURL *URL = [NSURL fileURLWithPath:path]; 
AVURLAsset *videoAssets = [[AVURLAsset alloc]initWithURL:URL options:nil]; 
AVMutableComposition* mixComposition = [AVMutableComposition composition]; 

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
AVAssetTrack *clipVideoTrack = [[videoAssets tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAssets.duration) 
           ofTrack:clipVideoTrack 
           atTime:kCMTimeZero error:nil]; 

[compositionVideoTrack setPreferredTransform:[[[videoAssets tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; 
//Add image 
UIImage *myImage = [UIImage imageNamed:@"Frame-1.png"]; 
CALayer *aLayer = [CALayer layer]; 
aLayer.contents = (id)myImage.CGImage; 
aLayer.frame = CGRectMake(5, 25, 57, 57); //Needed for proper display. We are using the app icon (57x57). If you use 0,0 you will not see it 
aLayer.opacity = 0.65; //Feel free to alter the alpha here 
//Add text instead of image 
CGSize videoSize = [videoAssets naturalSize]; 
CATextLayer *titleLayer = [CATextLayer layer]; 
titleLayer.string = @"Text goes here"; 
titleLayer.font = CFBridgingRetain(@"Helvetica"); 
titleLayer.fontSize = videoSize.height/6; 
//?? titleLayer.shadowOpacity = 0.5; 
titleLayer.alignmentMode = kCAAlignmentCenter; 
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height/6); //You may need to adjust this for proper display 
//Sorts the layer in proper order 
CALayer *parentLayer = [CALayer layer]; 
CALayer *videoLayer = [CALayer layer]; 
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height); 
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height); 
[parentLayer addSublayer:videoLayer]; 
[parentLayer addSublayer:aLayer]; 
[parentLayer addSublayer:titleLayer]; //ONLY IF WE ADDED TEXT 
//Create composition 
AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition]; 
videoComp.renderSize = videoSize; 
videoComp.frameDuration = CMTimeMake(1, 30); 
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool  videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 
//Create instruction 


AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]); 

AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; 
videoComp.instructions = [NSArray arrayWithObject: instruction]; 
//Export 

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"]; 
NSString *destinationPath = [documentsDirectory stringByAppendingFormat:@"/utput_%@.mov", [dateFormatter stringFromDate:[NSDate date]]]; 

AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality]; 
exportSession.videoComposition=videoComp; 

exportSession.outputURL = [NSURL fileURLWithPath:destinationPath]; 
exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
[exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    switch (exportSession.status) 
    { 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"Export OK"); 
      if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(destinationPath)) { 
       UISaveVideoAtPathToSavedPhotosAlbum(destinationPath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil); 
      } 
      break; 
     case AVAssetExportSessionStatusFailed: 
      NSLog (@"AVAssetExportSessionStatusFailed: %@", exportSession.error); 
      break; 
     case AVAssetExportSessionStatusCancelled: 
      NSLog(@"Export Cancelled"); 
      break; 
    } 
}]; 
} 

Antwort

0

ich diesen Code verwendet, um Video mit Wasserzeichen zu erzeugen.

- (void)videoOutput{// 1 - Early exit if there's no video file selected 
if (!self.videoAsset) { 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please Load a Video Asset First" 
                delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [alert show]; 
    return; 
} 

// 2 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances. 
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init]; 

// 3 - Video track 
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo 
                    preferredTrackID:kCMPersistentTrackID_Invalid]; 
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration) 
        ofTrack:[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] 
        atTime:kCMTimeZero error:nil]; 

// 3.1 - Create AVMutableVideoCompositionInstruction 
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration); 

// 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation. 
AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
AVAssetTrack *videoAssetTrack = [[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
UIImageOrientation videoAssetOrientation_ = UIImageOrientationUp; 
BOOL isVideoAssetPortrait_ = NO; 
CGAffineTransform videoTransform = videoAssetTrack.preferredTransform; 
if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) { 
    videoAssetOrientation_ = UIImageOrientationRight; 
    isVideoAssetPortrait_ = YES; 
} 
if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) { 
    videoAssetOrientation_ = UIImageOrientationLeft; 
    isVideoAssetPortrait_ = YES; 
} 
if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) { 
    videoAssetOrientation_ = UIImageOrientationUp; 
} 
if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) { 
    videoAssetOrientation_ = UIImageOrientationDown; 
} 
[videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero]; 
[videolayerInstruction setOpacity:0.0 atTime:self.videoAsset.duration]; 

// 3.3 - Add instructions 
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil]; 

AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; 

CGSize naturalSize; 
if(isVideoAssetPortrait_){ 
    naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width); 
} else { 
    naturalSize = videoAssetTrack.naturalSize; 
} 

float renderWidth, renderHeight; 
renderWidth = naturalSize.width; 
renderHeight = naturalSize.height; 
mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight); 
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; 
mainCompositionInst.frameDuration = CMTimeMake(1, 30); 

NSLog(@"naturalSize %f %f", naturalSize.width, naturalSize.height); 

// no-op - override this method in the subclass 
// 1 - Set up the text layer 
CATextLayer *subtitle1Text = [[CATextLayer alloc] init]; 
[subtitle1Text setFont:@"Helvetica-Bold"]; 
[subtitle1Text setFontSize:20]; 
[subtitle1Text setFrame:CGRectMake(0, 0, size.width, 100)]; 
[subtitle1Text setString:@"Your Text.."]; 
[subtitle1Text setAlignmentMode:kCAAlignmentCenter]; 
[subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]]; 

// 2 - The usual overlay 
CALayer *overlayLayer = [CALayer layer]; 
[overlayLayer addSublayer:subtitle1Text]; 
overlayLayer.frame = CGRectMake(0, 0, size.width, size.height); 
[overlayLayer setMasksToBounds:YES]; 

CALayer *parentLayer = [CALayer layer]; 
CALayer *videoLayer = [CALayer layer]; 
parentLayer.frame = CGRectMake(0, 0, size.width, size.height); 
videoLayer.frame = CGRectMake(0, 0, size.width, size.height); 
[parentLayer addSublayer:videoLayer]; 
[parentLayer addSublayer:overlayLayer]; 

composition.animationTool = [AVVideoCompositionCoreAnimationTool 
          videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

// 4 - Get path 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent: 
         [NSString stringWithFormat:@"FinalVideo-%d.mov",arc4random() % 1000]]; 
NSURL *url = [NSURL fileURLWithPath:myPathDocs]; 

// 5 - Create exporter 
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition 
                    presetName:AVAssetExportPresetHighestQuality]; 
exporter.outputURL=url; 
exporter.outputFileType = AVFileTypeQuickTimeMovie; 
exporter.shouldOptimizeForNetworkUse = YES; 
exporter.videoComposition = mainCompositionInst; 
[exporter exportAsynchronouslyWithCompletionHandler:^{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (session.status == AVAssetExportSessionStatusCompleted) { 
    NSURL *outputURL = session.outputURL; 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputURL]) { 
     [library writeVideoAtPathToSavedPhotosAlbum:outputURL completionBlock:^(NSURL *assetURL, NSError *error){ 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       if (error) { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
        [alert show]; 
       } else { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved To Photo Album" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
        [alert show]; 
       } 
      }); 
     }]; 
    } 
} 

    }); 
}];} 

Versuchen Sie diesen Code. Es hat perfekt für mich gearbeitet. Hoffe, das wird auch für dich funktionieren.

+0

Ich erhalte keinen Fehler, wenn ich den Code benutze, aber meine Videodatei wird nach dem Hinzufügen von Wasserzeichen immer noch nicht im Dokumentenverzeichnis abgespielt.und die Funktion exportAsynchronicallyWithCompletionHandler wird nicht aufgerufen. @ Monika –

+0

Es ist eine asynchrone Methode, also musst du bis zum warten Prozess wurde abgeschlossen. Sie erhalten eine Warnung, wenn das Video gespeichert wurde. @NehaPurwar – Monika

+0

tatsächlich bekomme ich AVAssetExportSessionFailed. Kannst du mir sagen, was ich in diesem Code falsch mache? –

Verwandte Themen