![]() |
AW: Zeitcode
Da wir nicht wissen in welchem Kontext die Frage steht, sind alle "Lösungen" spekulativ.
Gruß K-H |
AW: Zeitcode
Um Rundungsfehler zu vermeiden, würde ich mit Sekunden und Frames rechnen. Wenn die maximale Anzahl der FPS überschritten wird, muss der Übertrag berücksichtigt werden.
Diese Lösung sollte mit allen Timecodes funktionieren die ganzzahlige fps haben (also z.B. nicht 23.976fps). Man muss lediglich die Konstante fps anpassen.
Delphi-Quellcode:
Ausgabe
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses Types, SysUtils, Math, StrUtils; type TCDTimecode = record h, m, s, f: Word; neg: Boolean; function GetSeconds: Integer; // h, m, s => seconds procedure SetSeconds(Seconds: Integer); procedure Add(const t: TCDTimecode); function GetAsString: String; procedure SetAsString(const tc: String); end; { TCDTimecode } procedure TCDTimecode.Add(const t: TCDTimecode); const fps = 75; var s: Integer; f: Integer; begin s := Self.GetSeconds + t.GetSeconds; f := Self.f; if Self.neg then f := -f; if t.neg then dec(f, t.f) else inc(f, t.f); if f<0 then begin inc(f, fps); dec(s); // Carry end else if f>=fps then begin dec(f, fps); inc(s); // Carry end; SetSeconds(s); Self.f := Word(f); end; function TCDTimecode.GetAsString: String; const sign: array [Boolean] of String = ('+', '-'); begin Result := Format('%s%.2d:%.2d:%.2d:%.2d', [sign[neg], h, m, s, f]) end; function TCDTimecode.GetSeconds: Integer; begin Result := h * SecsPerHour + m * SecsPerMin + s; if neg then Result := -Result; end; procedure TCDTimecode.SetAsString(const tc: String); var List: TStringDynArray; t: Integer; begin List := SplitString(tc, ':'); if length(List) = 4 then begin t := StrToInt(List[0]); neg := t<0; h := abs(t); m := StrToInt(List[1]); s := StrToInt(List[2]); f := StrToInt(List[3]); end else raise Exception.CreateFmt('invalid timecode "%s"', [tc]); end; procedure TCDTimecode.SetSeconds(Seconds: Integer); begin neg := Seconds<0; divmod(Cardinal(abs(Seconds)), SecsPerHour, h, m); divmod(Cardinal(m), SecsPerMin, m, s); end; var t1, t2: TCDTimecode; begin try t1.SetAsString('03:00:00:12'); t2.SetAsString('-01:00:00:12'); t1.Add(t2); writeln(t1.GetAsString); t1.SetAsString('03:00:00:12'); t2.SetAsString('-01:00:00:13'); t1.Add(t2); writeln(t1.GetAsString); readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. +02:00:00:00 +01:59:59:74 |
AW: Zeitcode
Zitat:
|
AW: Zeitcode
Zitat:
Bei Musik-CDs hat Frames meines Erachtens nur Sinn wenn CD eine non-Stop CD ist (übergangsfreie Trackwechsel / Mix-CD). Bei Videos hat Frames Einfluss auf die aktuelle Position zwischen den einzelnen Sekunden/Millisekunden, abhängig wie das Video kodiert ist. Also gilt nach wie vor erst mal zu klären: Zitat:
Zitat:
Zitat:
|
AW: Zeitcode
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Falls jemand braucht, für ältere Delphi Versionen die noch kein SplitString() haben, im Anhang ist angepasstes Projekt. Ps: TStrings mit ExtractStrings() habe ich verwendet. |
AW: Zeitcode
Manchmal denke ich einfach zu kompliziert. Wenn man gleich mit fps arbeitet, wird es einfacher (man bekommt aber auch früher einen Überlauf: ab so rund 16000h 8000h):
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses Types, SysUtils, Math, StrUtils; type TCDTimecode = record Frames: Integer; function GetAsString: String; procedure SetAsString(const tc: String); end; const fps = 75; FramesPerHour = SecsPerHour * fps; FramesPerMin = SecsPerMin * fps; { TCDTimecode } function TCDTimecode.GetAsString: String; const sign: array [Boolean] of String = ('+', '-'); var t: Cardinal; h, m, s, f: Word; neg: Boolean; begin neg := Frames<0; t := abs(Frames); h := t div FramesPerHour; dec(t, h * FramesPerHour); divmod(t, FramesPerMin, m, s); divmod(Cardinal(s), fps, s, f); Result := Format('%s%.2d:%.2d:%.2d:%.2d', [sign[neg], h, m, s, f]) end; procedure TCDTimecode.SetAsString(const tc: String); var List: TStringDynArray; begin List := SplitString(tc, ':'); if length(List) = 4 then begin Frames := StrToInt(List[0]); Frames := Frames * MinsPerHour + StrToInt(List[1]); Frames := Frames * SecsPerMin + StrToInt(List[2]); Frames := Frames * fps + StrToInt(List[3]); end else raise Exception.CreateFmt('invalid timecode "%s"', [tc]); end; var t1, t2: TCDTimecode; begin try t1.SetAsString('03:00:00:12'); t2.SetAsString('01:00:00:12'); dec(t1.Frames, t2.Frames); writeln(t1.GetAsString); t1.SetAsString('03:00:00:12'); t2.SetAsString('01:00:00:13'); dec(t1.Frames, t2.Frames); writeln(t1.GetAsString); readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: Zeitcode
Liste der Anhänge anzeigen (Anzahl: 1)
Danke an samso, Anhang angepasst für ältere Delphis.
|
AW: Zeitcode
Zitat:
Delphi-Quellcode:
.
Int64
|
AW: Zeitcode
Klar kann man machen.. Meine Bemerkung war eher ironisch gemeint. Wer braucht schon einen Zeitcode mit 8000h (bei CD-Timecode?)?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz