0

I'm using Mplayer to extrac audio from video via command line. This is the command i use:

mplayer -ao pcm:fast:file=aaa.wav aaa.avi

I copied Mplayer.exe and aaa.avi both on windows drive (C:) and on the root directory of an external hard drive (in my case X).

When i execute from C the dumping start at normal speed (i see the video on real time) and aaa.wav is not created by Mplayer.

When i execute form X the dumping start at fast speed (as requested by the -ao pcm:fast audio driver) and the aaa.wav is correctly created.

I have the same issue in my app, here the code i use to do it:

public static string DumpWav_ConsoleOutput = "";
        public static int DumpWav_ProcessID = 0;
        Process DumpWav_Process = null;

        private void DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
        {
            //cancelliamo le variabili
            DumpWav_ConsoleOutput = "";
            //Handle della finestra di Media Player
            Variables.MediaPlayerHandle = 0;
            Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
            Thread thread = new Thread(() => _DumpWav(SourceFileName, DestinationFileName, NeedToCut,Start, End)); //il thread principale di Dump Wav
            thread.Start();
            while (thread.IsAlive) //aspettiamo il suo completamento
            {
                Application.DoEvents();
            }
            var myForm = new Output();
            myForm.SetOutputText = Variables.ConsoleOutputMP;
            myForm.Show();
            Variables.MediaPlayerExit = true;
            // ok il processo è terminato
        }

        private void _DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
        {
            string Output;
            Output = RunDumpWav((output) => { }, SourceFileName, DestinationFileName, NeedToCut, Start, End);
        }


        // Media Player avviato da questa funzione
        public string RunDumpWav(Action<string> output, string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
        {
            if (output == null)
                throw new ArgumentNullException("output");
            string args;
            ProcessStartInfo ps = new ProcessStartInfo();
            ps.FileName = FindMediaPlayerPath("mplayer.exe");
            ps.UseShellExecute = false;
            ps.RedirectStandardInput = true;
            ps.RedirectStandardError = true;
            ps.RedirectStandardOutput = true;
            ps.CreateNoWindow = true;
            ps.WorkingDirectory = @"x:\";
            args = "-wid ";
            args += Variables.MediaPlayerHandle;
            args += " -ao pcm:fast:file=";
            args += DestinationFileName;
            if (NeedToCut == true)
            {
                args += " -ss " + Start + " -endpos " + End;
            }
            //args += " -vo null -vc null -quiet ";
            //-wid will tell MPlayer to show output inisde our panel
            args += " " + SourceFileName;
            ps.Arguments = args;

            using (DumpWav_Process = Process.Start(ps))


            using (ManualResetEvent mreOut = new ManualResetEvent(false),
            mreErr = new ManualResetEvent(false))
            {
                DumpWav_Process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
                DumpWav_Process.BeginOutputReadLine();

                DumpWav_Process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); }; ;
                DumpWav_Process.BeginErrorReadLine();

                output = s => DumpWav_ElaborateOutput(s);

                DumpWav_ProcessID = DumpWav_Process.Id;
                //processMP.StandardInput.Close();
                DumpWav_Process.WaitForExit();
                mreOut.WaitOne();
                mreErr.WaitOne();
                //stringa di ritorno (tutto il contenuto della console)
                return DumpWav_ConsoleOutput;
            }
        }

        //controlliamo l'output della console
        private void DumpWav_ElaborateOutput(string output)
        {
            Variables.ConsoleOutputMP = Variables.ConsoleOutputMP + output + Environment.NewLine;
            if (output.IndexOf("A:") != -1)
            {
//some check here
            }

        }

I recently added this:

ps.WorkingDirectory = @"x:\";

But the result not change, the video speed is not fast and the wav file is not created by Mplayer.

In my app, like the C test, i receive some errors:

[AO PCM] Failed to open aaa.wav for writing!
Failed to initialize audio driver 'pcm:fast:file=aaa.wav'

One more question, when i use mPlayer to encapsulate videos inside my app the process start about one minute after i launched it... maybe concatenate with dumping issue?

Please, any suggestion?

Edit: I discovered just now: If i start the command prompt with admin rights then also in C Drive Mplayer do the job in the right way... My app unfortunately don't. I edited the manifest to grant admin rights but it's the same. Somewhere here at stackoverflow i read something about to useshellexecute to true but unfortunately by this way (i need to test anyway) i lose the ability to redirect input/output/error.

I need to find a way to start the process (then the mplayer.exe) from within my app, with admin rights, without use shellexecute...

Edit 2° I created a simple button with this code:

            string args;
            //Handle della finestra di Media Player
            Variables.MediaPlayerHandle = 0;
            Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = FindMediaPlayerPath("mplayer.exe");
            //psi.FileName = @"x:\mplayer.exe";
            psi.UseShellExecute = true;
            psi.CreateNoWindow = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.WorkingDirectory = Environment.CurrentDirectory; ;
            psi.Verb = "runas";
            args = "-wid ";
            args += Variables.MediaPlayerHandle;
            args += " -ao pcm:fast:file=";
            args += @"x:\aaa.wav";
            args += @" x:\aaa.avi";
            psi.Arguments = args;
            Process.Start(psi);

:-( same result, Mplayer is not able to open audio driver and to save file..

Fail, again.. 3° edit: I tried using CMD:

        private void button2_Click(object sender, EventArgs e)
        {
            ProcessStartInfo processInfo;
            Process process;
            Variables.MediaPlayerHandle = 0;
            Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
            string args = "";
            args = @"x:\mplayer.exe -wid " + Variables.MediaPlayerHandle + @" -ao pcm:fast:file=x:\aaa.wav x:\aaa.avi";
            MessageBox.Show(args);
            processInfo = new ProcessStartInfo("cmd.exe", "/c " + args);
            processInfo.CreateNoWindow = true;
            processInfo.UseShellExecute = true;
            processInfo.Verb = "runas";
            process = Process.Start(processInfo);
            process.WaitForExit();
            MessageBox.Show("terminato");

            process.Close();
        }

Now i see the first frame of the video and Mplayer freeze...

I'm losing my hope to use mplayer :-(

WizardingStudios
  • 554
  • 2
  • 7
  • 22
  • How about start your apps using "Run as administrator" ? Because C drive is very protective. –  Jun 30 '16 at 23:16
  • I just tried to start first Visual Studio as admin (nothing changed) and after the release build (same result). I'm trying now to elevate entire app with a manifest (UAC) – WizardingStudios Jun 30 '16 at 23:23
  • I mean, if you are using Process.Start, you must also add "runas" in it. See this example: http://stackoverflow.com/questions/4106628/start-process-with-administrator-right-in-c-sharp –  Jun 30 '16 at 23:28
  • I found five minutes ago the "runas" tip. Tried without success. I also changed the app manifest to request admin (and rebuilded) but no UAC prompt. I think i allready have admin rights... – WizardingStudios Jun 30 '16 at 23:36
  • Another similar answer was to useshellexecute to true but i should not do it because i really need to redirect standard output. – WizardingStudios Jun 30 '16 at 23:37
  • Pointed the mplayer to the one of the X drive: psi.FileName = @"x:\mplayer.exe"; Now the player start in less than one second (before it was over 60 seconds to start) but it continue to receive wrong permission to create the wav file and the dumbing speed is not fast :-( – WizardingStudios Jun 30 '16 at 23:49
  • Sorry, never use mplayer before, I use only ffmpeg, and it is really good. The bad side is only the file size, it is very big. –  Jun 30 '16 at 23:57
  • Don't worry Stanley and thanks for the help anyway!! I doubt it should be a problem related to Mplayer. I discovered just now that if i open the command prompt with admin rights also in C the Mplayer do the job right. Now i must find a way to use it from within my app with admin rights :-( – WizardingStudios Jul 01 '16 at 00:08
  • I just test it in my pc, it works. Need only this line "processInfo.Verb = "runas";" to start that process as admin and nothing else. –  Jul 01 '16 at 00:31
  • Here: [link](http://stackoverflow.com/questions/16926232/run-process-as-administrator-from-a-non-admin-application) Second comment for the main question say " The Verb only works with UseShellExecute set to true. – Dark Falcon Jun 4 '13 at 19:55".... unfortunately :-( – WizardingStudios Jul 01 '16 at 00:39
  • No, only 1 line with "runas", nothing else. My login user is admin. But if your login user is not admin, you must provide somehow username and password too... –  Jul 01 '16 at 00:44

1 Answers1

0

Finally i solved...

This is the code:

    if (output == null)
        throw new ArgumentNullException("output");
    string args;
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = FindMediaPlayerPath("mplayer.exe");
    //psi.FileName = @"x:\mplayer.exe";
    psi.UseShellExecute = false;
    psi.RedirectStandardInput = true;
    psi.RedirectStandardError = true;
    psi.RedirectStandardOutput = true;
    psi.CreateNoWindow = true;
    psi.WorkingDirectory = Path.GetDirectoryName(DestinationFileName);
    psi.Verb = "runas";
    args = "-wid ";
    args += Variables.MediaPlayerHandle;
    args += " -ao pcm:fast:file=";
    args += Path.GetFileName(DestinationFileName);
    if (NeedToCut == true)
    {
        args += " -ss " + Start + " -endpos " + End;
    }
    //args += " -vo null -vc null -quiet ";
    //-wid will tell MPlayer to show output inisde our panel
    args += " " + SourceFileName;
    psi.Arguments = args;

As i understand i need to move the Process.WorkingDirectory to the same folder as the destination file (in my case the wav).

Now it rocks :-)

NO need for UAC NO need for useshellexecute = true

Thanks stanley for your help!

WizardingStudios
  • 554
  • 2
  • 7
  • 22