1

我正在执行以下操作:

  1. 我在 Delphi XE2 程序中使用 FFMPEG 将收到的任何文件转换为 mp4 文件。
  2. 转换后,我还使用 qr-faststart 将原子移动到文件的开头。

问题是在转换某些文件(并非总是)后,qr-faststart 会出现以下错误:

  • “遇到非 QT 顶级原子(这是 QuickTime 文件吗?)”
  • “文件中的最后一个原子不是 moov 原子”

FFMPEG 的命令行是:-i "sourceFile" -sameq "destinationFile"

qt-faststart 的命令行是"sourceFile" "destFile"

这是两个函数的完整代码:

function TfrmMain.ConvertFile(aVideoFile: String; var aNewFile: String): Boolean;
var SEInfo: TShellExecuteInfo;
    ExitCode: DWORD;
    ExecuteFile, ParamString, StartInString: string;
    tmpVideoFile : String;
    logCommand   : String;
begin
  logMain.WriteFeedBackMessage(Format('enter ConvertFile %S ...', [aVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
  Result := False;
  StartInString := edConverterPath.Text;
  tmpVideoFile  := ExtractFileName(aVideoFile);
  aNewFile      := ChangeFileExt(tmpVideoFile, '.mp4');
  if tmpVideoFile = aNewFile then begin
    logMain.WriteFeedBackMessage('the file is already converted ...', '', EVENTLOG_INFORMATION_TYPE, False);
    if OptimizeFastStart(aVideoFile) then begin
      Result := True;
    end;
    Exit;
  end;
  aNewFile := ExtractFilePath(aVideoFile) + aNewFile;
  if FileExists(aNewFile) then begin
    DeleteFile(aNewFile);
  end;
  logCommand := '';
  if ckLog.Checked then begin
    logCommand := ' -loglevel verbose -report';
  end;
  ParamString := '-i "' + aVideoFile + '" -sameq "' + aNewFile + '" ' + logCommand;
  logMain.WriteFeedBackMessage(Format('ParamString %S', [ParamString]), '', EVENTLOG_INFORMATION_TYPE, False);
  ExecuteFile := IncludeTrailingBackslash(StartInString) + 'ffmpeg.exe';
  if FileExists(ExecuteFile) then begin
    FillChar(SEInfo, SizeOf(SEInfo), 0) ;
    SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
    with SEInfo do begin
      fMask := SEE_MASK_NOCLOSEPROCESS;
      Wnd := Application.Handle;
      lpFile := PChar(ExecuteFile) ;
      //ParamString can contain the application parameters.
      lpParameters := PChar(ParamString) ;
      //  StartInString specifies the  name of the working directory. If ommited, the current directory is used.
      lpDirectory := PChar(StartInString) ;
      nShow := SW_SHOWNORMAL;
    end;
    if ShellExecuteEx(@SEInfo) then begin
      repeat
        Application.ProcessMessages;
        GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
      until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
    end;
    if FileExists(aNewFile) then begin
      logMain.WriteFeedBackMessage(Format('Converting Video %S succesfull!', [aVideoFile]), Format('File %S was created.', [aNewFile]), EVENTLOG_INFORMATION_TYPE, True, False, False);
      if OptimizeFastStart(aNewFile) then begin
        Result := True;
      end;
    end;
  end else begin
    logMain.WriteFeedBackMessage(Format('File %S does not exist on the server!', [ExecuteFile]), 'The converter cannot be located on the disk!' + #13#10 + ExecuteFile, EVENTLOG_ERROR_TYPE, True, False, False);
  end;
end;

快速开始就在这里

function TfrmMain.OptimizeFastStart(aVideoFile: String): Boolean;
var SEInfo: TShellExecuteInfo;
    ExitCode: DWORD;
    ExecuteFile, ParamString, StartInString: string;
    strVideoFile : String;
    newVideoFile : String;
    startCommand : String;
begin
  // you need fast start utility
  logMain.WriteFeedBackMessage(Format('enter OptimizeFastStart %S ...', [aVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
  Result := False;
  StartInString := edConverterPath.Text;
  strVideoFile  := ExtractFileName(aVideoFile);
  newVideoFile  := 'TMP_' + strVideoFile;
  if strVideoFile = aVideoFile then begin
    strVideoFile  := StartInString + strVideoFile;
    newVideoFile  := StartInString + newVideoFile;
  end;
  if not FileExists(strVideoFile) then begin
    logMain.WriteFeedBackMessage(Format('file %S dont exist...', [strVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
    Exit;
  end;
  if FileExists(newVideoFile) then begin
    DeleteFile(newVideoFile);
  end;

  ParamString := Format('"%S" "%S"', [strVideoFile, newVideoFile]);
  ExecuteFile := IncludeTrailingBackslash(StartInString) + 'qt-faststart.exe';
  if FileExists(ExecuteFile) then begin
    logMain.WriteFeedBackMessage(Format('source %S destination %S', [strVideoFile, newVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
    FillChar(SEInfo, SizeOf(SEInfo), 0) ;
    SEInfo.cbSize := SizeOf(TShellExecuteInfo);
    with SEInfo do begin
      fMask := SEE_MASK_NOCLOSEPROCESS;
      Wnd := Application.Handle;
      lpFile := PChar(ExecuteFile) ;
      lpParameters := PChar(ParamString);
      lpDirectory  := PChar(StartInString);
      nShow        := SW_SHOWNORMAL;
    end;
    if ShellExecuteEx(@SEInfo) then begin
      repeat
        Application.ProcessMessages;
        GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
      until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
    end;
    logMain.WriteFeedBackMessage(Format('after file executed...', [strVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
    sleep(500);
    Application.ProcessMessages;
    if FileExists(newVideoFile) then begin
      DeleteFile(strVideoFile);
      Application.ProcessMessages;
      sleep(500);
      Application.ProcessMessages;
      logMain.WriteFeedBackMessage(Format('before rename file...', [strVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
      if RenameFile(newVideoFile, strVideoFile) then begin
        logMain.WriteFeedBackMessage(Format('rename file OK...', [strVideoFile]), '', EVENTLOG_INFORMATION_TYPE, False);
        Result := True;
        logMain.WriteFeedBackMessage(Format('Processing Video %S for WEB succesfull!', [strVideoFile]), '', EVENTLOG_INFORMATION_TYPE, True);
      end;
    end else begin
      logMain.WriteFeedBackMessage(Format('file %S does not exist!...', [newVideoFile]), '', EVENTLOG_INFORMATION_TYPE, True);
    end;
  end else begin
    logMain.WriteFeedBackMessage('Cannot find the qt-faststart.exe converter on the disk!', ExecuteFile, EVENTLOG_ERROR_TYPE, True);
  end;
end;

谁能建议我如何解决这个问题。

4

1 回答 1

0

去掉 -sameq 选项,不代表质量一样。另外,你有什么版本的FFMpeg?如果您没有最新的,请更新。那应该可以解决您的问题。您可以发布完整的命令行输出吗?

于 2013-03-13T09:59:37.510 回答