裁剪从相机拍摄的视频

时间:2015-08-04 06:23:38

标签: ios xamarin xamarin.ios avfoundation crop

我正在使用Xamarin.iOS裁剪从移动摄像头拍摄的视频。我已经成功实现了下面的代码,它正在完美地用于风景视频,但是在裁剪了肖像视频之后,它返回了右侧的黑色区域。它。以下是修剪代码和结果图像。任何建议都会有所帮助,我们将不胜感激。

void CropVideo()
{
        var cropWidth=(cropperView.CropRect.Width/cropperView.Frame.Width)*videoAsset.NaturalSize.Width;
        var cropHeight=(cropperView.CropRect.Height/cropperView.Frame.Height)*videoAsset.NaturalSize.Height;
        AVMutableComposition videoComposition =  AVMutableComposition.Create();
        AVMutableCompositionTrack compositionTrack = videoComposition.AddMutableTrack (AVMediaType.Video, 0);
        AVAssetTrack clipVideoToTrack = videoAsset.TracksWithMediaType (AVMediaType.Video)[0];
        AVMutableVideoComposition VideoComposition= AVMutableVideoComposition.Create();
        VideoComposition.RenderSize = new CGSize (cropWidth,cropHeight);
        VideoComposition.FrameDuration = new CMTime (1,videoAsset.Duration.TimeScale);
        AVMutableVideoCompositionInstruction instruction = new AVMutableVideoCompositionInstruction ();
        var timeRange = new CMTimeRange ();
        timeRange.Start = new CMTime (0, videoAsset.Duration.TimeScale);
        timeRange.Duration = new CMTime (videoAsset.Duration.Value,videoAsset.Duration.TimeScale);
        instruction.TimeRange = timeRange;
        AVMutableVideoCompositionLayerInstruction transform = AVMutableVideoCompositionLayerInstruction.FromAssetTrack (clipVideoToTrack);
        var orientation = GetVideoOrientationFromAsset (clipVideoToTrack);
        var cropY=(cropperView.CropRect.Y/cropperView.Frame.Height)*videoAsset.NaturalSize.Height;
        var cropX=(cropperView.CropRect.X/cropperView.Frame.Width)*videoAsset.NaturalSize.Width;
        var translationTransform = CGAffineTransform.MakeIdentity ();
        var rotationTransform = CGAffineTransform.MakeIdentity ();
        switch (orientation) 
        {
        case UIImageOrientation.Up:
            translationTransform=CGAffineTransform.MakeTranslation (videoAsset.NaturalSize.Height-cropX,0- cropY);
            rotationTransform = CGAffineTransform.Rotate (translationTransform,(nfloat)Math.PI/2);
            break;
        case UIImageOrientation.Down:
            translationTransform=CGAffineTransform.MakeTranslation (0-cropX,videoAsset.NaturalSize.Width- cropY);
            rotationTransform = CGAffineTransform.Rotate (translationTransform,(nfloat)(-Math.PI/2));
            break;
        case UIImageOrientation.Right:
            translationTransform=CGAffineTransform.MakeTranslation (0-cropX,0- cropY);
            rotationTransform = CGAffineTransform.Rotate (translationTransform,(nfloat)0);
            break;
        case UIImageOrientation.Left:
            translationTransform=CGAffineTransform.MakeTranslation (videoAsset.NaturalSize.Width-cropX,videoAsset.NaturalSize.Height- cropY);
            rotationTransform = CGAffineTransform.Rotate (translationTransform,(nfloat)Math.PI);
            break;
        }
         transform.SetTransform (rotationTransform, new CMTime (0, videoAsset.Duration.TimeScale));
        instruction.LayerInstructions = new AVVideoCompositionLayerInstruction[]{ transform};
        VideoComposition.Instructions = new AVVideoCompositionInstruction[]{ instruction};
        var compatiblePresets= AVAssetExportSession.ExportPresetsCompatibleWithAsset(videoAsset).ToList();
        var preset="";
        if(compatiblePresets.Contains("AVAssetExportPresetLowQuality"))
        {
            preset="AVAssetExportPresetLowQuality";
        }
        else
        {
            preset=compatiblePresets.FirstOrDefault();
        }
        AVAssetExportSession export= new AVAssetExportSession(videoAsset,preset);
        export.VideoComposition = VideoComposition;
        int SystemVersion = Convert.ToInt16(UIDevice.CurrentDevice.SystemVersion.Split('.')[0]);
        string filename;
        if (SystemVersion >= 8)
        {
            var documents = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0].Path;
            filename = Path.Combine(documents, "cropped.mov");
        }
        else
        {
            var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // iOS 7 and earlier
            filename = Path.Combine(documents, "cropped.mov");
        }
        var url = NSUrl.FromFilename (filename);
        NSError error;
        var manager =NSFileManager.DefaultManager;
        manager.Remove(url,out error);
        export.OutputUrl = url;
        export.OutputFileType = AVFileType.QuickTimeMovie;
        var bounds = UIScreen.MainScreen.Bounds; // portrait bounds
        if (UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeLeft || UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeRight) {
            bounds.Size = new CGSize(bounds.Size.Height, bounds.Size.Width);
        }
        // show the loading overlay on the UI thread using the correct orientation sizing
        var overlay = new LoadingOverlay (bounds,"Cropping Video");
        this.View.Add ( overlay );
        export.ExportAsynchronously (() => {
            InvokeOnMainThread(()=>{
                overlay.Hide();
            });
            if(export.Status==AVAssetExportSessionStatus.Completed)
            {
                ALAssetsLibrary library = new ALAssetsLibrary();
                library.WriteVideoToSavedPhotosAlbumAsync(url);
                page.VideoCroppped(filename);
            }
            else
            {
                InvokeOnMainThread(()=>{
                new UIAlertView("Not Awesome",export.Error.Description,null,"O K").Show();
                });
            }
        });     
   }

UIImageOrientation GetVideoOrientationFromAsset (AVAssetTrack videoTrack)
    {
        CGSize size = videoTrack.NaturalSize;
        CGAffineTransform txf = videoTrack.PreferredTransform;

        if (size.Width == txf.x0 && size.Height == txf.y0)
            return UIImageOrientation.Left; //return UIInterfaceOrientationLandscapeLeft;
        else if (txf.x0 == 0 && txf.y0 == 0)
            return UIImageOrientation.Right; //return UIInterfaceOrientationLandscapeRight;
        else if (txf.x0 == 0 && txf.y0 == size.Width)
            return UIImageOrientation.Down; //return UIInterfaceOrientationPortraitUpsideDown;
        else
            return UIImageOrientation.Up;  //return UIInterfaceOrientationPortrait;
    }

enter image description here

0 个答案:

没有答案