我正在执行以下操作:
- 我在 Delphi XE2 程序中使用 FFMPEG 将收到的任何文件转换为 mp4 文件。
- 转换后,我还使用 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;
谁能建议我如何解决这个问题。