首页 > 解决方案 > Error "2 input names specified, please check usage" while saving video file in desired path

问题描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using WMPLib;

namespace Mp4BoxSplitter {
  public partial class Form1: Form {
    public Form1() {
      InitializeComponent();
    }

    private void BOpen_Click(object sender, EventArgs e) {
      if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        tFileName.Text = openFileDialog1.FileName;
        this.axWindowsMediaPlayer1.URL = tFileName.Text;
      }
    }

    private void BStartTime_Click(object sender, EventArgs e) {
      tStartTime.Text = axWindowsMediaPlayer1.Ctlcontrols.currentPosition.ToString("0.##");
    }

    private void BEndTime_Click(object sender, EventArgs e) {
      tEndTime.Text = axWindowsMediaPlayer1.Ctlcontrols.currentPosition.ToString("0.##");
    }

    private void BCutSave_Click(object sender2, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.stop();

      //pokličem mp4box.exe s parametri                        
      Process p = new Process();
      p.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mp4box", @ "mp4box.exe");

      string sStartTime = decimal.Parse(tStartTime.Text).ToString("0.##").Replace(",", ".");
      string sEndTime = decimal.Parse(tEndTime.Text).ToString("0.##").Replace(",", ".");

      string inFileName = tFileName.Text;
      string outFileName = inFileName.Substring(0, inFileName.LastIndexOf(".")) + "_" + sStartTime + "-" + sEndTime + inFileName.Substring(inFileName.LastIndexOf("."));

      string @params = "-splitx " + sStartTime + ":" + sEndTime + " " + inFileName + " -out " + outFileName;

      Debug.WriteLine(p.StartInfo.FileName + " " + @params);

      p.StartInfo.Arguments = @params;

      var sb = new StringBuilder();
      sb.AppendLine("mp4box.exe results:");
      // redirect the output
      p.StartInfo.RedirectStandardOutput = true;
      p.StartInfo.RedirectStandardError = true;
      // hookup the eventhandlers to capture the data that is received
      p.OutputDataReceived += (sender, args) => {
        if (args.Data != null && !args.Data.StartsWith("Splitting:") && !args.Data.StartsWith("ISO File Writing:")) {
          sb.AppendLine(args.Data);
        }
      };
      p.ErrorDataReceived += (sender, args) => {
        if (args.Data != null && !args.Data.StartsWith("Splitting:") && !args.Data.StartsWith("ISO File Writing:")) {
          sb.AppendLine(args.Data);
        }
      };

      // direct start
      p.StartInfo.UseShellExecute = false;

      p.Start();
      // start our event pumps
      p.BeginOutputReadLine();
      p.BeginErrorReadLine();

      // until we are done
      p.WaitForExit();
      tResult.Text = sb.ToString();
    }

    private void TFileName_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Enter) {
        this.axWindowsMediaPlayer1.URL = tFileName.Text;
      }
    }

    private void TFileName_DragEnter(object sender, DragEventArgs e) {
      if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
        e.Effect = DragDropEffects.Copy;
      } else {
        e.Effect = DragDropEffects.None;
      }
    }

    private void TFileName_DragDrop(object sender, DragEventArgs e) {
      if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
        string[] files = (string[]) e.Data.GetData(DataFormats.FileDrop);
        tFileName.Text = files[0];
        this.axWindowsMediaPlayer1.URL = tFileName.Text;
      }
    }

    private void BMinus1Sec_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= 1;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BMinus5Sec_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= 5;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BMinus10s_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= 10;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BToStart_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 0;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BPlus1Sec_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition += 1;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BPlus5Sec_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition += 5;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BPlus10Sec_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition += 10;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BToEnd_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition = axWindowsMediaPlayer1.currentMedia.duration;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BMinusDot5_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= 0.5;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BMinusDot2_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition -= 0.2;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BPlusDot5_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition += 0.5;
      axWindowsMediaPlayer1.Refresh();
    }

    private void BPlusDot2_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition += 0.2;
      axWindowsMediaPlayer1.Refresh();

    }

    private void BPlusFrame_Click(object sender, EventArgs e) {
      ((IWMPControls2) axWindowsMediaPlayer1.Ctlcontrols).step(1);
      axWindowsMediaPlayer1.Refresh();
    }

    private void Button1_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.pause();
    }

    private void BPlayPart_Click(object sender, EventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.currentPosition = double.Parse(tStartTime.Text);
      double dInterval = (double.Parse(tEndTime.Text) - double.Parse(tStartTime.Text)) * 1000;

      System.Timers.Timer aTimer = new System.Timers.Timer();
      aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
      aTimer.Interval = dInterval;

      axWindowsMediaPlayer1.Ctlcontrols.play();
      aTimer.Enabled = true;

    }
    private void OnTimedEvent(object sender, ElapsedEventArgs e) {
      axWindowsMediaPlayer1.Ctlcontrols.pause();
      var timer = (System.Timers.Timer) sender;
      timer.Dispose();
    }

    private void BExplore_Click(object sender, EventArgs e) {
      string sFolderPath = Path.GetDirectoryName(tFileName.Text);

      ProcessStartInfo startInfo = new ProcessStartInfo {
        Arguments = sFolderPath,
          FileName = "explorer.exe"
      };
      Process.Start(startInfo);
    }
  }
}

After loading mp4 file and selecting start and end times then when clicking the Cut + Save button it will throw an error :

private void BCutSave_Click(object sender2, EventArgs e) {
  axWindowsMediaPlayer1.Ctlcontrols.stop();

  //pokličem mp4box.exe s parametri                        
  Process p = new Process();
  p.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mp4box", @ "mp4box.exe");

  string sStartTime = decimal.Parse(tStartTime.Text).ToString("0.##").Replace(",", ".");
  string sEndTime = decimal.Parse(tEndTime.Text).ToString("0.##").Replace(",", ".");

  string inFileName = tFileName.Text;
  string outFileName = inFileName.Substring(0, inFileName.LastIndexOf(".")) + "_" + sStartTime + "-" + sEndTime + inFileName.Substring(inFileName.LastIndexOf("."));

  string @params = "-splitx " + sStartTime + ":" + sEndTime + " " + inFileName + " -out " + outFileName;

  Debug.WriteLine(p.StartInfo.FileName + " " + @params);

  p.StartInfo.Arguments = @params;

  var sb = new StringBuilder();
  sb.AppendLine("mp4box.exe results:");
  // redirect the output
  p.StartInfo.RedirectStandardOutput = true;
  p.StartInfo.RedirectStandardError = true;
  // hookup the eventhandlers to capture the data that is received
  p.OutputDataReceived += (sender, args) => {
    if (args.Data != null && !args.Data.StartsWith("Splitting:") && !args.Data.StartsWith("ISO File Writing:")) {
      sb.AppendLine(args.Data);
    }
  };
  p.ErrorDataReceived += (sender, args) => {
    if (args.Data != null && !args.Data.StartsWith("Splitting:") && !args.Data.StartsWith("ISO File Writing:")) {
      sb.AppendLine(args.Data);
    }
  };

  // direct start
  p.StartInfo.UseShellExecute = false;

  p.Start();
  // start our event pumps
  p.BeginOutputReadLine();
  p.BeginErrorReadLine();

  // until we are done
  p.WaitForExit();
  tResult.Text = sb.ToString();
}

It will not get into the line :

sb.AppendLine(args.Data);

but will jump to the lines :

p.ErrorDataReceived += (sender, args) => {
    if (args.Data != null && !args.Data.StartsWith("Splitting:") && !args.Data.StartsWith("ISO File Writing:")) {
        sb.AppendLine(args.Data);
    }
};

The error is :

mp4box.exe results:
Error - 2 input names specified, please check usage

标签: c#

解决方案


Perhaps your tFileName.Text; has spaces in it and you've ended up making a command line like mp4box.exe -splitx 1:2 C:\program files\some\file.ext -out blah.mp4 and mp4box thinks that your two input files are c:\program and files\some\file.ext.

To fix issues with running another command from C# the process is typically:

  • Use the debugger to find out exactly what arguments string has been built - put a breakpoint on the var sb = new StringBuilder(); and look at the value of the p.StartInfo.Arguments in the Locals or Autos panel
  • Copy that string (right click and choose Copy Value)
  • Run it yourself directly in a command prompt (paste it in after the path to the mp4box.exe)
  • Fix any issues (e.g. add " around any paths with spaces) so that mp4box runs successfully in the command prompt, and then transport the fixes you made on the command line into the code, for example:
     string @params = $"-splitx {sStartTime}:{sEndTime} \"{inFileName}\" -out \"{outFileName}\"";

ps; use string interpolation. It's a lot more readable than concatenation for this kind of thing


推荐阅读