Einzelnen Beitrag anzeigen

nezumi7

Registriert seit: 11. Apr 2011
71 Beiträge
 
#10

AW: mp4 Cut and Merge

  Alt 21. Mär 2015, 09:00
den Quellcode werde ich erst mal bereinigen, da ich da selbst kaum noch durchblicke. 90% davon ist aber auch reine Fleißarbeit (Optik, Hinweise usw.) und daher nicht wirklich interessant.

Für die Videoanzeige hab ich DSPack genommen. Der relevante Code für Video-Infos auslesen und fürs Schneiden und Zusammenfügen ist:

Delphi-Quellcode:

function RunCaptured(const _exeName, _cmdLine: string): String;
var
  TmpName: string;
  TmpSec: TSecurityAttributes;
  Tmp: Windows.THandle;
  Start: TStartupInfo;
  ProcInfo: TProcessInformation;
  Res: TStringList;
  Return: Cardinal;
begin
  try
    TmpName := 'Test.tmp';
    FillChar(TmpSec, SizeOf(TmpSec), #0);
    TmpSec.nLength := SizeOf(TmpSec);
    TmpSec.bInheritHandle := True;

    Tmp := Windows.CreateFile(PChar(TmpName),
           Generic_Write, File_Share_Write,
           @TmpSec, Create_Always, File_Attribute_Normal, 0);

    try
      FillChar(Start, SizeOf(Start), #0);
      Start.cb := SizeOf(Start);
      Start.hStdOutput := Tmp;
      Start.dwFlags := StartF_UseStdHandles or StartF_UseShowWindow;
      Start.wShowWindow := SW_Hide;

      if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,0, nil, nil, Start, procInfo) then
      begin
        SetPriorityClass(ProcInfo.hProcess, Idle_Priority_Class);
        WaitForSingleObject(ProcInfo.hProcess, Infinite);
        GetExitCodeProcess(ProcInfo.hProcess, Return);
        CloseHandle(ProcInfo.hThread);
        CloseHandle(ProcInfo.hProcess);
        Windows.CloseHandle(Tmp);
        Res := TStringList.Create;
        try
          Res.LoadFromFile(TmpName);
          Result := Res.Text;
        finally
          Res.Free;
        end;

        Windows.DeleteFile(PChar(TmpName));
      end
        else
      begin
        Application.MessageBox(PChar(SysErrorMessage(GetLastError())),
          'RunCaptured Error', MB_OK);
        //result := 'Fehler: '+PChar(SysErrorMessage(GetLastError()))
      end;

    except
      Windows.CloseHandle(tmp);
      Windows.DeleteFile(PChar(tmpName));
      raise;
    end;
  finally {} end;
end;


//Video Info auslesen:
s := RunCaptured([pfad ffprobe.exe], ' -select_streams v -show_streams [pfad video]');

//i-frames finden:
s := RunCaptured([pfad ffprobe.exe], ' -show_frames -select_streams v [pfad video]');

//Schnitt mit ffmpeg:
RunCaptured([pfad ffmpeg.exe], ' -i '+[pfad video]+' -ss [Schnitt Anfang] -t [Schnitt Ende] -acodec copy -vcodec copy [Speicherort output]');
//Schnitt Anfang und Ende: String (Zeit in Sekunden), z.B. '128.240' für 128 Sekunden, 240 Millisekunden

//Schnitt mit mp4box
Shellexecute(0,nil,PChar([pfad mp4box.exe]),PChar('[pfad video] -splitx [Schnitt Anfang]:[Schnitt Ende] -out [Speicherort output]'),nil,SW_hide);

//zusammenfügen ffmpeg:
Shellexecute(0,nil,PChar([pfad ffmpeg.exe]),PChar(' -f concat -i [C:\text.txt] -codec copy [Speicherort output]'),nil,SW_hide);
//Aufbau der temporären Datei text.txt:
//file C:\xy1.mp4
//file C:\xy2.mp4
//file C:\xy3.mp4

//zusammenfügen mp4box:
procedure TForm1.Button2Click(Sender: TObject); //Speicherorte der Teildateien in Listbox2
var
i,lc: Integer;
aufruf, outpath, mp4boxpath: String;
begin
mp4boxpath := ExtractFilePath(ParamStr(0))+'mp4box.exe';
   If FileExists(mp4boxpath) then begin
   outpath := 'C:\~temp\';
   ForceDirectories(outpath);
   lc := Listbox2.Items.Count;
      If lc > 1 then begin
         aufruf := 'mp4box';
         for i := 0 to Listbox2.Items.Count-1 do begin
         aufruf := aufruf+' -cat '+Listbox2.Items[i];
         end;
         aufruf := aufruf+' -out '+outpath;
         RunCaptured(mp4boxpath, aufruf);
      end else begin
      ShowMessage('Choose at least two mp4-files!');
      end;
   end else begin
   ShowMessage('mp4box not found!');
   end;
end;
Ist aber auch alles ganz gut dokumentiert auf den Seiten von ffmpeg und mp4box
  Mit Zitat antworten Zitat