2

我目前正在使用PBJVision开发 iOS 应用程序,并尝试以正确的方向保存横向视频。

我使用 writeVideoAtPathToSavedPhotosAlbum: completionBlock: 方法将照片保存到设备:

[self.library writeVideoAtPathToSavedPhotosAlbum: videoPathURL
                                 completionBlock:^(NSURL* assetURL, NSError* error) {

    [self encodeVideoOrientation:assetURL]; // method below

    if (error.code == 0) {

          [self.library assetForURL:assetURL 
             resultBlock:^(ALAsset *asset) {
             // assign the video to the album
             }
             failureBlock:^(NSError* error) {
                 NSLog(@"Failed to save video to library");
           }];
     } else {
     }
}];

然后我在我编写的名为encodeVideoOrientation的方法中使用保存的视频的assetURL ,目的是用旋转的视频覆盖文件。请注意,我对所有视频应用相同的旋转(90 度)以进行测试 - 但无论方向如何,都不会对视频应用任何变换。

- (void)encodeVideoOrientation:(NSURL *)anOutputFileURL
{
    CGAffineTransform rotationTransform;
    CGAffineTransform transformToApply = videoAsset.preferredTransform;
    CGSize renderSize;
    CGFloat newWidth;
    CGFloat newHeight;
    float currentVideoRotation;

    AVURLAsset * videoAsset = [[AVURLAsset alloc]initWithURL:anOutputFileURL options:nil];
    AVAssetTrack *sourceVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVAssetTrack *sourceAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

    CGSize size = [sourceVideoTrack naturalSize];

    // below, I test rotating the video regardless of orientation to check if portrait videos become rotated, which they do not

    if (self.currentOrientationByAccelerometer == LANDSCAPE_RIGHT){
       currentVideoRotation = M_PI; // for testing, video should appear upside down
       newWidth = size.height;
       newHeight = size.width;
       NSLog(@"Should be landscape right");
    } else if (self.currentOrientationByAccelerometer == LANDSCAPE_LEFT){
       currentVideoRotation = M_PI; //for testing, should appear upside down
       newWidth = size.height;
       newHeight = size.width;
       NSLog(@"Should be landscape left");
    } else { //default to portrait
       currentVideoRotation = M_PI; 
       newWidth = size.width;
       newHeight = size.height;
       NSLog(@"Should be portrait");
    }

    renderSize = CGSizeMake(newWidth, newHeight);
    rotationTransform = CGAffineTransformMakeRotation(currentVideoRotation);    

    AVMutableComposition* composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
     [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil];
     [compositionVideoTrack setPreferredTransform:rotationTransform]; //Rotations here?

     AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
     [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:sourceAudioTrack atTime:kCMTimeZero error:nil];

     AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
     AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];
     [layerInstruction setTransform:transformToApply atTime:kCMTimeZero]; //Rotations here?
     instruction.layerInstructions = [NSArray arrayWithObject: layerInstruction];

     AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
     videoComposition.frameDuration = CMTimeMake(1,30);
     videoComposition.renderScale = 1.0;
     videoComposition.renderSize = renderSize;
     instruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
     videoComposition.instructions = [NSArray arrayWithObject: instruction];

     AVAssetExportSession * assetExport = [[AVAssetExportSession alloc] initWithAsset:composition                                                                    presetName:AVAssetExportPresetMediumQuality];

     NSString* videoName = @"export.mov";
     NSString *anOutputFileURLPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];

     NSURL * exportUrl = [NSURL fileURLWithPath:anOutputFileURLPath];

     if ([[NSFileManager defaultManager]  fileExistsAtPath:anOutputFileURLPath])
     {
         [[NSFileManager defaultManager] removeItemAtPath:anOutputFileURLPath error:nil];
      }

      assetExport.outputFileType = AVFileTypeMPEG4;
      assetExport.outputURL = exportUrl;
      assetExport.shouldOptimizeForNetworkUse = YES;
      assetExport.videoComposition = videoComposition;

      [assetExport exportAsynchronouslyWithCompletionHandler: ^(void ) {
         switch (assetExport.status)
         {
             case AVAssetExportSessionStatusCompleted:
             //                export complete
             NSLog(@"Export Complete");
             break;
         case AVAssetExportSessionStatusFailed:
             NSLog(@"Export Failed");
             NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
             //                export error (see exportSession.error)
             break;
         case AVAssetExportSessionStatusCancelled:
             NSLog(@"Export Cancelled");
             NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
             //                export cancelled
             break;
     }
 }];

}

导出成功完成,但无论 CGAffineTransform 如何,似乎都没有对视频应用任何转换。

我在编写代码时引用了这个 SO 帖子:

iOS AVFoundation:设置视频方向

根据项目 github 上的这篇文章,这似乎是一个未解决的问题:

https://github.com/piemonte/PBJVision/issues/84

如何保存使用 PBJVision 捕获的旋转视频?

4

0 回答 0