투명도가있는 다른 비디오로 비디오를 워터 마크하려면 AVFoundation을 사용하고 있습니다. 다음 코드를 사용하여 하나의 비디오를 다른 비디오 위에 겹쳐 넣을 수 있었지만 투명도가있는 에셋을 사용하자마자 유용한 오류없이 내보내기가 실패합니다.iOS - 투명한 비디오가있는 워터 마크 비디오
This link 알파 채널에 관해서 AVFoundation이 지원하는 유일한 코덱 인 PreRes 4444가 있지만, 이에 대한 공식 문서는 찾을 수 없습니다. 나는 현재 오버레이로 추가하려고 파일은
ProRes를 코덱은 OS X에서 사용할 수있는 것을 말한다 곳, Learning AVFoundation을 읽은 후에 최선의 선택이 될 것 같은 H.264 인코딩 된 MP4입니다 iOS 전용으로 을 개발하는 경우 H264가 유일한 게임입니다.
비디오 오버레이 대신 항상 애니메이션 레이어를 추가 할 수는 있지만, 이에 대한 해결책이없는 경우에는 놀랄 것입니다.
- (void)addWatermarkToAsset:(NSURL *)assetURL completionHandler:(void (^)(NSURL *videoURL))handler
{
AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
// This asset contains an alpha channel, and has a shorter duration than videoAsset
NSURL *animationUrl = [[NSBundle mainBundle] URLForResource:@"InstagramAnimation" withExtension:@"mp4"];
AVURLAsset *animationAsset = [AVURLAsset URLAssetWithURL:animationUrl options:nil];
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *animationTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[animationTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, animationAsset.duration)
ofTrack:[[animationAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
CGAffineTransform scale = CGAffineTransformMakeScale(0.7f,0.7f);
CGAffineTransform move = CGAffineTransformMakeTranslation(230,230);
[videoLayerInstruction setTransform:CGAffineTransformConcat(scale, move) atTime:kCMTimeZero];
AVMutableVideoCompositionLayerInstruction *animationLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:animationTrack];
CGAffineTransform secondScale = CGAffineTransformMakeScale(1.2f,1.5f);
CGAffineTransform secondMove = CGAffineTransformMakeTranslation(0,0);
[animationLayerInstruction setTransform:CGAffineTransformConcat(secondScale, secondMove) atTime:kCMTimeZero];
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videoLayerInstruction, animationLayerInstruction, nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
mainCompositionInst.renderSize = videoTrack.naturalSize;
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];
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(), ^{
[self exportDidFinish:exporter];
});
}];
}
큰 감사입니다. OpenGL 쉐이더를 사용한 솔루션이 너무 많은 시간을 소비하는 것처럼 보였으므로 AfterEffects 애니메이션을 코드의 사용자 지정 애니메이션으로 변환하는 결과를 낳았습니다. 그러나 확실히 당신의 솔루션을 시험해 볼 것입니다. –