Registriert seit: 11. Apr 2011
71 Beiträge
|
AW: mp4 Cut and Merge
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
|