2016-05-13 13 views
1

私はビデオ作成アプリで作業しています。
私は最初のビューでビデオを録画する必要があり、2番目のビューではそのディスプレイの後に録画する必要があります。
ビデオを録画する場合は、thisチュートリアルに従ってください。 私はdidFinishRecordingToOutputFileAtURL方法で私の必要性に応じていくつかの変更を加えました。iosでのビデオ録画の問題

ここに私の更新された方法があります。

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error 
{ 
    NSLog(@"didFinishRecordingToOutputFileAtURL - enter"); 

    BOOL RecordedSuccessfully = YES; 
    if ([error code] != noErr) 
    { 
     // A problem occurred: Find out if the recording was successful. 
     id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey]; 
     if (value) 
     { 
      RecordedSuccessfully = [value boolValue]; 
     } 
    } 
    else { 
     NSLog(@"didFinishRecordingToOutputFileAtURL error:%@",error); 
    } 
    if (RecordedSuccessfully) 
    { 
     //----- RECORDED SUCESSFULLY ----- 
     NSLog(@"didFinishRecordingToOutputFileAtURL - success"); 
     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
     if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL]) 
     { 
      AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init]; 
      AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 

      AVAsset *asset = [AVAsset assetWithURL:outputFileURL]; 

      [track insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:CMTimeMake(0, 1) error:nil]; 

      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
      NSString *documentsDirectory = [paths objectAtIndex:0]; 
      NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent: 
            [NSString stringWithFormat:@"%@%d.mov",NSBundle.mainBundle.infoDictionary[@"CFBundleExecutable"],++videoCounter]]; 
      [[NSFileManager defaultManager] removeItemAtPath:myPathDocs error:nil]; 

      NSURL *url = [NSURL fileURLWithPath:myPathDocs]; 

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

      AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:track]; 
      AVAssetTrack *videoAssetTrack = [[asset 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 ([[[NSUserDefaults standardUserDefaults] stringForKey:@"orientation"] isEqualToString:@"landscape"]) { 
        videoAssetOrientation_ = UIImageOrientationUp; 
       } 
      } 
      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; 
      } 

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

      float renderWidth, renderHeight; 
      if (![self.ratioLabel.text isEqualToString:@"16:9"]) { 
       renderWidth = naturalSize.width; 
       renderHeight = naturalSize.width; 
       NSLog(@"Video:: width=%f height=%f",naturalSize.width,naturalSize.height); 
      } 
      else { 
       renderWidth = naturalSize.width; 
       renderHeight = naturalSize.height; 
       NSLog(@"Video:: width=%f height=%f",naturalSize.width,naturalSize.height); 
      } 
      if (![self.ratioLabel.text isEqualToString:@"16:9"]) 
      { 
       CGAffineTransform t1 = CGAffineTransformMakeTranslation(videoAssetTrack.naturalSize.height, -(videoAssetTrack.naturalSize.width - videoAssetTrack.naturalSize.height) /2); 
       CGAffineTransform t2 = CGAffineTransformRotate(t1, M_PI_2); 
       [layerInstruction setTransform:t2 atTime:kCMTimeZero]; 
      } 
      else 
      { 
       CGAffineTransform t2 = CGAffineTransformMakeRotation(M_PI_2); 
       [layerInstruction setTransform:t2 atTime:kCMTimeZero]; 
      } 

      AVCaptureDevicePosition position = [[VideoInputDevice device] position]; 
      if (position == AVCaptureDevicePositionFront) 
      { 
       /* For front camera only */ 
       CGAffineTransform t = CGAffineTransformMakeScale(-1.0f, 1.0f); 
       t = CGAffineTransformTranslate(t, -videoAssetTrack.naturalSize.width, 0); 
       t = CGAffineTransformRotate(t, (DEGREES_TO_RADIANS(90.0))); 
       t = CGAffineTransformTranslate(t, 0.0f, -videoAssetTrack.naturalSize.width); 
       [layerInstruction setTransform:t atTime:kCMTimeZero]; 
       /* For front camera only */ 
      } 

      [layerInstruction setOpacity:0.0 atTime:asset.duration]; 

      instruction.layerInstructions = [NSArray arrayWithObjects:layerInstruction,nil]; 

      AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; 


      mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight); 
      mainCompositionInst.instructions = [NSArray arrayWithObject:instruction]; 
      mainCompositionInst.frameDuration = CMTimeMake(1, 30); 

      AVAssetExportSession *exporter; 
      exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPreset1280x720]; 
      exporter.videoComposition = mainCompositionInst; 
      exporter.outputURL=url; 
      exporter.outputFileType = AVFileTypeQuickTimeMovie; 
      exporter.shouldOptimizeForNetworkUse = YES; 

      [exporter exportAsynchronouslyWithCompletionHandler:^{ 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        self.doneButton.userInteractionEnabled = YES; 
        if(videoAddr==nil) 
        { 
         videoAddr = [[NSMutableArray alloc] init]; 
        } 
        [videoAddr addObject:exporter.outputURL]; 
        [[PreviewLayer connection] setEnabled:YES]; 
        AVAsset *asset = [AVAsset assetWithURL:exporter.outputURL]; 
        NSLog(@"remaining seconds before:%f",lastSecond); 
        double assetDuration = CMTimeGetSeconds(asset.duration); 
        if (assetDuration>3.0) 
         assetDuration = 3.0; 
        lastSecond = lastSecond- assetDuration; 
        NSLog(@"remaining seconds after:%f",lastSecond); 
        self.secondsLabel.text = [NSString stringWithFormat:@"%0.1fs",lastSecond]; 
        self.secondsLabel.hidden = NO; 
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:videoAddr]; 

        [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"videoAddr"]; 
        [[NSUserDefaults standardUserDefaults] synchronize]; 
        videoURL = outputFileURL; 
        flagAutorotate = NO; 
        self.cancelButton.hidden = self.doneButton.hidden = NO; 
        imgCancel.hidden = imgDone.hidden = NO; 
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Vibration"]) 
         AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); 
        [[UIApplication sharedApplication] endIgnoringInteractionEvents]; 
       }); 
      }]; 
     } 
     else { 
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Video can not be saved\nPlease free some storage space"] delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil]; 
      [alert show]; 
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
       [alert dismissWithClickedButtonIndex:0 animated:YES]; 
      }); 
     } 

    } 
} 

しかし、ここに問題があります。
ビデオがプレビューに正確に表示されていません。 2つのスクリーンショットをご覧ください。

ビデオ録画プレビュー

Video recording preview
ビデオは、あなたのiPadの画面のアスペクト比はカメラのアスペクト比と同じではありませんので、理由があるビュー

Video Playing View

+1

をお使いのビデオ録画ビューは、私はそれが記録中のすべての側面からのいくつかの部分を隠すと思うあなたの画面サイズよりも大きいようです! – Lion

+0

が原因である可能性があります。私はiPad(4:3)とビデオ解像度でテストしています。私は1280 * 720(16:9)を与えています.... –

+0

5秒でテストしました。だから、これはVladimir K –

答えて

1

を再生します。

layer.videoGravity = AVLayerVideoGravityResizeAspect; 

をしかし、その場合のプレビューでフルスクリーンではありません。

あなたはコンテンツがレイヤーの境界に関連して見てどのように影響AVCaptureVideoPreviewLayervideoGravity財産、 を設定することで、カメラのプレビューのサイズを変更することができます。

ビデオをプレビュー全画面と同じアスペクト比で表示するには、それを切り抜かなければなりません。トリミングプロセスは、ここで説明:

Exporting AVCaptureSession video in a size that matches the preview layer

Video capture with 1:1 aspect ratio in iOS

+0

のおかげで、提案されたようにiPadで解決することができます、バディ....試してみます –

+0

問題はありません。私はそれが助けて欲しい –

+0

私は 'AVLayerVideoGravityResizeAspectFill'を設定する必要があります。私が' AVLayerVideoGravityResizeAspect'を設定すると、私の1:1プレビューも16:9として表示されます。あなたの親切なおかげでよろしく。 –