2016-08-29 15 views
2

私はAVFoundationを使って透かしを入れた別のビデオで透かしを入れています。次のコードを使用して、1つのビデオを他のビデオの上にオーバーレイすることができましたが、透明性を持つアセットを使用し始めると、エクスポートは役に立たないエラーなしで失敗します。iOS - 透明なビデオの透かしのビデオ

This linkアルファチャンネルに関しては、AVRoundationがサポートする唯一のコーデックはPreRes 4444ですが、それに関する正式なドキュメントは見つかりません。私は現在、オーバーレイがLearning AVFoundationを読んだ後に最良の選択であるように思わH.264エンコードのMP4、あるとして追加しようとしていたファイル、それは

たProResコーデックはのみOS X上で利用可能であることを述べてあなたが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]; 
     }); 
    }]; 
} 

答えて

1

私はH264内部
1.カスタム透明度のフォーマットをすることによって、これをやった、と
2.カスタム(PERFORCEの)カスタム透明形式のコンポジ

は、カスタム形式でした各カラーフレームがその白黒マスクの真上にある「高さの高い」ビデオ。

コンポジターは、透かしとファイルに透かしを入れ、それらを合成し、その結果を第3のファイルに書き込んだ。 各フレームの各ピクセルはYUV値として解釈され、1つは色として、もう1つはマスクとして使用され、背景フレームと結合されました。

コンポジットはOpenGLピクセルシェーダ+ TextureCachesでしたが、今日はMetalCVMetalTextureCacheを使用します。

+1

大変感謝します。 AfterEffectsアニメーションをコード内のカスタムアニメーションに変換することになりました。なぜなら、OpenGLシェーダを使用したソリューションは時間がかかりすぎたようです。しかし、間違いなくあなたのソリューションを試してみましょう。 –

関連する問題