使用FFMPEG转换文件...文件末尾没有MOOV ATOM

时间:2013-03-13 08:29:13

标签: video ffmpeg qt-faststart

我正在做以下事情:

  1. 我将FFMPEG用于Delphi XE2程序,将我收到的任何文件转换为mp4文件。
  2. 我还使用qr-faststart将原子移动到转换后的文件开头。
  3. 问题是在转换某些文件后(并非总是),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;
    

    任何人都可以建议我如何解决这个问题。

1 个答案:

答案 0 :(得分:0)

删除-sameq选项,它并不意味着相同的质量。另外,你有什么版本的FFMpeg?如果您没有最新的更新。这应该可以解决你的问题。你可以发布完整的命令行输出吗?