肖像

2017-02-17 10 views
0

更新肖像

は、映像翻訳をテストするために、シミュレータを使用しないでください。しかし、私はコーデックの問題 を別の質問で尋ねましたhere。どんな助けもありがとうございます。

私はAVURLAssetを使用して自分のビデオを作成していますが、ギャラリーから選択したビデオがランドスケープモードの間は問題ありません。しかし、私がポートレートビデオを使用するときは、黒い画面(オーディオ再生)で再生するか、フレームがねじれています(画像を参照)。

更新: 私はCGAffineTransformを使用してみましたが、まだ運がありません。

ここでは、コードです:

-(void) createVideo{ 

    AVMutableComposition* mixComposition = [AVMutableComposition composition]; 
    NSDictionary *options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES}; 


    _videoAsset = [[AVURLAsset alloc]initWithURL:video_url options:options]; 

    CMTime startTimeV=CMTimeMakeWithSeconds(videoStartTime.floatValue, 1); 
    CMTime endTimeV=CMTimeMakeWithSeconds(videoEndTime.floatValue, 1); 

    CMTimeRange video_timeRange = CMTimeRangeMake(startTimeV,endTimeV); 



    AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[_videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil]; 

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

    AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:a_compositionVideoTrack]; 
    AVAssetTrack *videoAssetTrack = [[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 

    CGSize trackDimensions = { 
     .width = 0.0, 
     .height = 0.0, 
    }; 
    trackDimensions = [videoAssetTrack naturalSize]; 

    int width = trackDimensions.width; 
    int height = trackDimensions.height; 


    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; 
    } 
// CGAffineTransform transformToApply=CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90.0)); 

    [videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero]; 
    [videolayerInstruction setOpacity:0.0 atTime:self.videoAsset.duration]; 

    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); 

と輸出:

-(void)export{ 

     NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *docsDir = [dirPaths objectAtIndex:0]; 
     NSString* fileName=[NSString stringWithFormat:@"myvideo%lld.mp4",[@(floor([[NSDate date] timeIntervalSince1970])) longLongValue]+1]; 

     NSString *outputFilePath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",fileName]]; 

     NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath]; 
     if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath]) 
      [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil]; 


     AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; 
     _assetExport.outputFileType = AVFileTypeMPEG4; 
     _assetExport.outputURL = outputFileUrl; 
     _assetExport.videoComposition = mainCompositionInst; 

     ShareViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"vidShare"]; 

     [_assetExport exportAsynchronouslyWithCompletionHandler: 
     ^(void) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 

       newViewController.videoFilePath=outputFileUrl; 
[self.navigationController pushViewController:newViewController animated:YES]; 

      }); 
     } 
     ]; 
    } 

風景= OK

Landscape Video = OK

肖像= FAIL

Portrait Video = FAIL

答えて

0

私は前にこの問題を持っていました。 videoAssetTrack.preferredTransformを使用してvideolayerInstructionのトランスフォームを設定すると、ほとんどの場合に機能します。しかし、時にはpreferredTransformはtx(ty)の価値がないかもしれません(CxffineTransformでApple API Referenceでtx(ty)が分からない場合)かtx(ty)に不正確な値があり、黒い画面で再生するように)。
要点は、preferredTransformを使用して原点のビデオ方向を決定し、独自のトランスフォームを作成する必要があります。ここ
は、トラックの向きを取得するコードは次のとおりです。必要なを取得するための

- (UIInterfaceOrientation)orientationForTrack:(AVAsset *)asset { 
    UIInterfaceOrientation orientation = UIInterfaceOrientationPortrait; 
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; 

    if([tracks count] > 0) { 
     AVAssetTrack *videoTrack = [tracks objectAtIndex:0]; 
     CGAffineTransform t = videoTrack.preferredTransform; 

     // Portrait 
     if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0) { 
      orientation = UIInterfaceOrientationPortrait; 
     } 
     // PortraitUpsideDown 
     if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0) { 
      orientation = UIInterfaceOrientationPortraitUpsideDown; 
     } 
     // LandscapeRight 
     if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0) { 
      orientation = UIInterfaceOrientationLandscapeRight; 
     } 
     // LandscapeLeft 
     if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0) { 
      orientation = UIInterfaceOrientationLandscapeLeft; 
     } 
    } 
    return orientation; 
} 

とコードvideolayerInstructionの変換に適用する変換:

- (CGAffineTransform)transformBasedOnAsset:(AVAsset *)asset { 
    UIInterfaceOrientation orientation = [AVUtilities orientationForTrack:asset]; 
    AVAssetTrack *assetTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0]; 
    CGSize naturalSize = assetTrack.naturalSize; 
    CGAffineTransform finalTranform; 
    switch (orientation) { 
     case UIInterfaceOrientationLandscapeLeft: 
      finalTranform = CGAffineTransformMake(-1, 0, 0, -1, naturalSize.width, naturalSize.height); 
      break; 
     case UIInterfaceOrientationLandscapeRight: 
      finalTranform = CGAffineTransformMake(1, 0, 0, 1, 0, 0); 
      break; 
     case UIInterfaceOrientationPortrait: 
      finalTranform = CGAffineTransformMake(0, 1, -1, 0, naturalSize.height, 0); 
      break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      finalTranform = CGAffineTransformMake(0, -1, 1, 0, 0, naturalSize.width); 
      break; 
     default: 
      break; 
    } 
    return finalTranform; 
} 

はそれがあなたのために働く願っています。

+0

まだ動作しません –

+0

それはうまくいきませんでした。ソースビデオを提供することができれば、デバッグするのがはるかに簡単です。 – zhoujialei

+0

私はそれがおそらく動作しなかったと言ってはいけません。問題はコーデックであり、コーデックH.264 AACでは機能しません:( –

関連する問題