如何以xamarin形式压缩(Zip)视频

时间:2018-04-20 11:18:10

标签: c# xamarin.forms

我想压缩一个大尺寸的视频并将其上传到服务器。我怎么能这样做,我对此一无所知。

请帮助我....

2 个答案:

答案 0 :(得分:1)

首先 - 压缩视频内容不太可能以任何有意义的方式减小其大小。 您应该关注的是不同的编解码器和编码机制,以减小其大小。

请看ffmpeg:ffmpeg dot org

您可以通过System.Diagnostics.Process类在命令行上调用此工具。 然后,您可以告诉它处理视频文件。 这将允许您更改视频使用的编码和编解码器。 注意 - 缩小尺寸会降低视频质量。 您可能还希望缩小视频的分辨率以获得最大的缩小。

视频和音频是无法使用传统工具(如winzip或winrar)压缩的媒体类型,最终会显示较小的文件。 通常,您最终只会将文件大小减少1%。 要减小文件大小,您需要更改视频编码,这在某些情况下会降低质量。

ffmpeg -i myVideo.avi -fs 20M myOutputVideo.avi

此命令行将采用100 mb或更大的myVideo.avi,并尝试降级质量/编码比特率以获得20mb的输出大小。

public static void ShrinkVideo(string pathToVideo,int desiredMbSize,string outFile)
{
     ProcessStartInfo psi = new ProcessStartInfo("ffmpeg.exe");
     psi.Arguments = string.Format("-i \"{0}\" -fs {1}M \"{2}\"",pathToVideo,desiredMbSize,outFile);
     Process proc = new Process(psi);
     proc.Start();
}

我还没有测试过这段代码 - 但它应该按照你想要的方式做一些事情。如果您收到错误 - 回复。

BTW-这依赖于ffmpeg.exe - 这是第三方可执行文件。 它通常被广泛使用 - 它被认为是最兼容和多功能的视频编码器之一 - 得到社区的很好支持。

答案 1 :(得分:1)

在Android的DS文件中使用以下代码

public Task CompressVideo(字符串路径)         {

        var task = new TaskCompletionSource<string>();

        var _workingDirectory = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
        var sourceMp4 = path;
        var destinationPath1 = IntentHelper.CreateNewVideoPath();
        FFMpeg ffmpeg = new FFMpeg(Android.App.Application.Context, _workingDirectory);
        TransposeVideoFilter vfTranspose = new TransposeVideoFilter(TransposeVideoFilter.NINETY_CLOCKWISE);
        var filters = new List<VideoFilter>();
        filters.Add(vfTranspose);

        Task.Run(() =>
        {
            var sourceClip = new Clip(System.IO.Path.Combine(_workingDirectory, sourceMp4)) { videoFilter = VideoFilter.Build(filters) };
            var onComplete = new MyCommand((_) =>
            {
                CurrentActivity.RunOnUiThread(() =>
                {
                    task.SetResult(destinationPath1);
                    //progress.Dismiss();
                });
            });

            var onMessage = new MyCommand((message) =>
            {
                System.Console.WriteLine(message);
            });

            var callbacks = new FFMpegCallbacks(onComplete, onMessage);
            string[] cmds = new string[] {
                    "-y",
                    "-i",
                    sourceClip.path,
                    "-strict", "experimental",
                    "-vcodec", "libx264",
                    "-preset", "ultrafast",
                    "-crf","38", "-acodec","aac", "-ar", "44100" ,
                    "-q:v", "12",
                      "-vf",sourceClip.videoFilter,
                    destinationPath1 ,
                      };
            ffmpeg.Execute(cmds, callbacks);
            return task.Task;
        });
        return task.Task;
    }

    public class MyCommand : ICommand
    {
        public delegate void ICommandOnExecute(object parameter = null);
        public delegate bool ICommandOnCanExecute(object parameter);

        private ICommandOnExecute _execute;
        private ICommandOnCanExecute _canExecute;

        public MyCommand(ICommandOnExecute onExecuteMethod)
        {
            _execute = onExecuteMethod;
        }

        public MyCommand(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod)
        {
            _execute = onExecuteMethod;
            _canExecute = onCanExecuteMethod;
        }

        #region ICommand Members

        public event EventHandler CanExecuteChanged
        {
            add { throw new NotImplementedException(); }
            remove { throw new NotImplementedException(); }
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null && _execute != null)
                return true;

            return _canExecute.Invoke(parameter);
        }

        public void Execute(object parameter)
        {
            if (_execute == null)
                return;

            _execute.Invoke(parameter);
        }

        #endregion
    }

现在在iOS的依赖关系文件中使用此代码

public Task CompressVideo(string inputPath)         {

        var task = new TaskCompletionSource<string>();
        var export = new AVAssetExportSession(AVAsset.FromUrl(new NSUrl(inputPath)), AVAssetExportSession.PresetMediumQuality);
        string videoFilename = System.IO.Path.Combine(GetVideoDirectoryPath(), GetUniqueFileName(".mp4"));
        export.OutputUrl = NSUrl.FromFilename(videoFilename);
        export.OutputFileType = AVFileType.Mpeg4;
        export.ShouldOptimizeForNetworkUse = true;
        export.ExportAsynchronously(() =>
        {
            if (export.Status == AVAssetExportSessionStatus.Completed)
            {
                var videoData = NSData.FromUrl(NSUrl.FromString(export.OutputUrl.ToString()));
                NSError err = null;
                if (videoData.Save(videoFilename, false, out err))
                    task.SetResult(videoFilename);
                else
                    task.SetResult(null);
            }
            else
                task.SetResult(null);
        });

        return task.Task;