示例#1
0
 internal StreamGobbler(SoxHelpers outerInstance, System.IO.Stream inputStream, string type, FFMpegCallbacks sc)
 {
     this.outerInstance = outerInstance;
     this.inputStream = inputStream;
     this.type = type;
     this.sc = sc;
 }
示例#2
0
 public LengthParser(SoxHelpers outerInstance, FFMpegCallbacks callbacks)
     : base(callbacks._completedAction, callbacks._messageAction)
 {
     _outerInstance = outerInstance;
     _messageAction = callbacks._messageAction;
     _completedAction= callbacks._completedAction;
 }
示例#3
0
 public SoxHelpers(Context context, int soxResId, Java.IO.File fileAppRoot, FFMpegCallbacks callback)
 {
     _globalCallback = callback;
     _context = context;
     InstallBinaries(soxResId, false);
     fileBinDir = (new File(soxBin)).ParentFile;
 }
示例#4
0
 public int ExecSox(IList<string> cmd, FFMpegCallbacks sc)
 {
     string soxBin = (new File(fileBinDir, "sox")).CanonicalPath;
     var r = Runtime.GetRuntime ();
     r.Exec("chmod 700 " + soxBin);
     return ExecProcess(cmd, sc);
 }
示例#5
0
        public static void CompressVideo(string inputPath, string outputPath, Action <string> callback)
        {
            Activity activity = new Activity();

            _callback = callback;
            ProgressDialog progress = new ProgressDialog(Forms.Context);

            progress.Indeterminate = true;
            progress.SetProgressStyle(ProgressDialogStyle.Spinner);
            progress.SetMessage("Compressing Video. Please wait...");
            progress.SetCancelable(false);
            progress.Show();

            Task.Run(() =>
            {
                var _workingDirectory            = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
                var sourceMp4                    = inputPath;
                var destinationPath1             = outputPath;
                FFMpeg ffmpeg                    = new FFMpeg(Android.App.Application.Context, _workingDirectory);
                TransposeVideoFilter vfTranspose = new TransposeVideoFilter(TransposeVideoFilter.NINETY_CLOCKWISE);
                var filters = new List <VideoFilter>();
                filters.Add(vfTranspose);

                var sourceClip = new Clip(System.IO.Path.Combine(_workingDirectory, sourceMp4))
                {
                    videoFilter = VideoFilter.Build(filters)
                };
                var br         = System.Environment.NewLine;
                var onComplete = new MyCommand((_) =>
                {
                    _callback(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", "30", "-acodec", "aac", "-ar", "44100",
                    "-q:v", "20",
                    "-vf", sourceClip.videoFilter,
                    // "mp=eq2=1:1.68:0.3:1.25:1:0.96:1",

                    destinationPath1,
                };
                ffmpeg.Execute(cmds, callbacks);
            });
        }
示例#6
0
        private int ExecProcess(IList<string> cmds, FFMpegCallbacks sc)
        {
            //ensure that the arguments are in the correct Locale format
            // TODO: Useless since SOX is called internally. Remove.
            for ( int i = 0; i < cmds.Count; i++)
            {
                cmds[i] = string.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US"), "%s", cmds[i]);
            }

            ProcessBuilder pb = new ProcessBuilder(cmds);
            pb.Directory(fileBinDir);

            var cmdlog = new Java.Lang.StringBuilder();

            foreach (string cmd in cmds)
            {
                cmdlog.Append(cmd);
                cmdlog.Append(' ');
            }

            sc.ShellOut(cmdlog.ToString());

            pb.RedirectErrorStream(true);
            var process = pb.Start();

            StreamGobbler errorGobbler = new StreamGobbler(this, process.ErrorStream, "ERROR", sc);
            StreamGobbler outputGobbler = new StreamGobbler(this, process.InputStream, "OUTPUT", sc);

            errorGobbler.Run();
            outputGobbler.Run();

            int exitVal = process.WaitFor();

            while (outputGobbler.IsAlive || errorGobbler.IsAlive);

            sc.ProcessComplete(exitVal);

            return exitVal;
        }
        void Start()
        {
            _workingDirectory = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var sourceMp4 = "cat1.mp4";
            var destinationPathAndFilename  = System.IO.Path.Combine(_workingDirectory, "cat1_out.mp4");
            var destinationPathAndFilename2 = System.IO.Path.Combine(_workingDirectory, "cat1_out2.mp4");
            var destinationPathAndFilename4 = System.IO.Path.Combine(_workingDirectory, "cat1_out4.wav");

            if (File.Exists(destinationPathAndFilename))
            {
                File.Delete(destinationPathAndFilename);
            }
            CreateSampleFile(Resource.Raw.cat1, _workingDirectory, sourceMp4);


            var ffmpeg = new FFMpeg(this, _workingDirectory);

            var sourceClip = new Clip(System.IO.Path.Combine(_workingDirectory, sourceMp4));

            var result = ffmpeg.GetInfo(sourceClip);

            var br = System.Environment.NewLine;

            // There are callbacks based on Standard Output and Standard Error when ffmpeg binary is running as a process:

            var onComplete = new MyCommand((_) => {
                RunOnUiThread(() => _logView.Append("DONE!" + br + br));
            });

            var onMessage = new MyCommand((message) => {
                RunOnUiThread(() => _logView.Append(message + br + br));
            });

            var callbacks = new FFMpegCallbacks(onComplete, onMessage);

            // 1. The idea of this first test is to show that video editing is possible via FFmpeg:
            // It results in a 150x150 movie that eventually zooms on a cat ear. This is desaturated, and there's a fade in.

            var filters = new List <VideoFilter> ();

            filters.Add(new FadeVideoFilter("in", 0, 100));
            filters.Add(new CropVideoFilter("150", "150", "0", "0"));
            filters.Add(new ColorVideoFilter(1.0m, 1.0m, 0.0m, 0.5m, 1.0m, 1.0m, 1.0m, 1.0m));
            var outputClip = new Clip(destinationPathAndFilename)
            {
                videoFilter = VideoFilter.Build(filters)
            };

            outputClip.H264_CRF = "18";             // It's the quality coefficient for H264 - Default is 28. I think 18 is pretty good.
            ffmpeg.ProcessVideo(sourceClip, outputClip, true, new FFMpegCallbacks(onComplete, onMessage));

            //2. This is a similar version version in command line only:
            string[] cmds = new string[] {
                "-y",
                "-i",
                sourceClip.path,
                "-strict",
                "-2",
                "-vf",
                "mp=eq2=1:1.68:0.3:1.25:1:0.96:1",
                destinationPathAndFilename2,
                "-acodec",
                "copy",
            };
            ffmpeg.Execute(cmds, callbacks);

            // 3. This lists codecs:
            string[] cmds3 = new string[] {
                "-codecs",
            };
            ffmpeg.Execute(cmds, callbacks);

            // 4. This convers to WAV
            // Note that the cat movie just has some silent house noise.
            ffmpeg.ConvertToWaveAudio(sourceClip, destinationPathAndFilename4, 44100, 2, callbacks, true);

            // Etc...

            // Rules of thumb:
            // a) Provide the minimum of info to ffmpeg to not mix it up
            // b) These helpers are cool to test capabilities, but useless otherwise, and crashy: Use command lines.
            // c) Try to compile a newer FFmpeg :)
        }
		public  MemoryStream CompressVideo( string sourceFilePath, string destinationFilePath, bool deleteSourceFile )
		{
			if (sourceFilePath == null || destinationFilePath == null)
				return null;

			MediaMetadataRetriever media = new MediaMetadataRetriever ();
			media.SetDataSource ( sourceFilePath );
			string videoRotation = media.ExtractMetadata ( MetadataKey.VideoRotation );


			XamarinAndroidFFmpeg.FFMpeg ffmpeg = new FFMpeg ( MainApplication.Context, App.DownloadsPath);
			var onComplete = new MyCommand ((_) => 
				{
					
				});

			var onMessage = new MyCommand ((message) => 
				{
					System.Diagnostics.Debug.WriteLine(  "---" + message);
				});


			if (videoRotation != null && videoRotation == "90")
			{
				string[] cmds = new string[] 
				{
					"-i",
					sourceFilePath,
					"-vcodec",
					"mpeg4",
					"-acodec",
					"aac",
					"-strict",
					"-2",
					"-ac",
					"1",
					"-ar",
					"16000",
					"-r",
					"13",
					"-ab",
					"32000",
					"-vf",
					"transpose=1",
					"-y",
					destinationFilePath
				};
				var callbacks = new FFMpegCallbacks (onComplete, onMessage);
				ffmpeg.Execute (cmds, callbacks);
			} 
			else 
			{
				string[] cmds = new string[] 
				{
					"-i",
					sourceFilePath,
					"-vcodec",
					"mpeg4",
					"-acodec",
					"aac",
					"-strict",
					"-2",
					"-ac",
					"1",
					"-ar",
					"16000",
					"-r",
					"13",
					"-ab",
					"32000",
					"-y",
					destinationFilePath
				};
				var callbacks = new FFMpegCallbacks (onComplete, onMessage);
				ffmpeg.Execute (cmds, callbacks);
			}
		

			if (deleteSourceFile) 
			{
				Java.IO.File toDel = new Java.IO.File ( sourceFilePath );
				toDel.Delete ();
			}


			MemoryStream ms = new MemoryStream();    
			FileStream file = new FileStream(  destinationFilePath, FileMode.Open, FileAccess.Read);
			file.CopyTo ( ms );
			file.Close();
			return ms;

		}
		public MemoryStream CreateVideoThumbnail ( string inputVideoPath, string outputImagePath )
		{

			MediaMetadataRetriever media = new MediaMetadataRetriever ();
			media.SetDataSource ( inputVideoPath );
			string videoRotation = media.ExtractMetadata ( MetadataKey.VideoRotation );

			XamarinAndroidFFmpeg.FFMpeg ffmpeg = new FFMpeg ( MainApplication.Context, App.DownloadsPath);
			var onComplete = new MyCommand ((_) => 
				{

				});

			var onMessage = new MyCommand ((message) => 
				{
					System.Diagnostics.Debug.WriteLine(  "---" + message);
				});

			var callbacks = new FFMpegCallbacks (onComplete, onMessage);

			if (videoRotation != null && videoRotation == "90") 
			{
				string[] cmds = new string[] {
					"-i",
					inputVideoPath,
					"-ss",
					"00:00:01.000",
					"-vf",
					"transpose=1",
					outputImagePath
				};
				ffmpeg.Execute (cmds, callbacks);
			} 
			else
			{
				string[] cmds = new string[]
				{
					"-i",
					inputVideoPath,
					"-ss",
					"00:00:01.000",
					outputImagePath
				};
				ffmpeg.Execute (cmds, callbacks);
			}

			MemoryStream ms = new MemoryStream ();
			FileStream stream = new FileStream (outputImagePath, FileMode.Open);
			stream.CopyTo (ms);
			return ms;

		}