Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Zeitcode (https://www.delphipraxis.net/197269-zeitcode.html)

Dilom 25. Jul 2018 14:39

Zeitcode
 
Hallo,

03:00:00:12 - 01:00:00:12 = 02:00:00:00 Wie kann ich berechnen?

TimeCodeInEdit 01:00:00:00
TimeCodeOutEdit 02:00:00:00
TimeCodeDurationEdit'e Edit2 - Edit1 = 01:00:00:00


S1, S2: TDateTime;
begin
S1 := StrToTime(Edit1.Text);
S2 := StrToTime(Edit2.Text);
Edit3.Text := (TimeToStr(S1 - S2));

Uwe Raabe 25. Jul 2018 14:41

AW: Zeitcode
 
Wieso machst bu bei jeder Korrektur einen neuen Thread auf?

Uwe Raabe 25. Jul 2018 14:42

AW: Zeitcode
 
Was soll denn dies bedeuten: 03:00:00:12?

mkinzler 25. Jul 2018 14:43

AW: Zeitcode
 
Ich habe die anderen Threads gelöscht.

DieDolly 25. Jul 2018 14:47

AW: Zeitcode
 
Ich würde es so machen. Ist nur eine Idee. Ungetestet.

Die Zeit erst einmal in Sekunden umrechnen (Funktion)
Delphi-Quellcode:
uses System.TimeSpan;

function TimeToMilliSeconds(TimeString: string): Double;
var
 TimeSpan: TTimeSpan;
begin
 TimeSpan := TTimeSpan.Parse(TimeString);
 Result := TimeSpan.TotalMilliseconds;
end;
Dann die Differenz berechnen
Delphi-Quellcode:

DifferenzMilliSekunden := (TimeToMilliSeconds(cIn) - TimeToMilliSeconds(cOut));

Das ist sicherlich auch ganz anders möglich mit TDateTime (StrToDateTime) oder anders.

KodeZwerg 25. Jul 2018 15:29

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408665)
03:00:00:12 - 01:00:00:12 = 02:00:00:00 Wie kann ich berechnen?

Wahrscheinlich gar nicht da diese Kombination wenig Sinn ergibt, ansonsten würde ich
Delphi-Quellcode:
SecondsBetween(TDateTime1,TDateTime2)
Vorschlagen, damit hast Du die Differenz in Sekunden, die einfach wieder in Std:Min:Sek hochrechnen. Millisekunden besteht aus 4 Ziffern weswegen ich einfach mal von einem Schreibfehler ausgeh.

Uwe Raabe 25. Jul 2018 15:32

AW: Zeitcode
 
Zitat:

Zitat von KodeZwerg (Beitrag 1408673)
Millisekunden besteht aus 4 Ziffern

Ähemm, 3?

KodeZwerg 25. Jul 2018 15:34

AW: Zeitcode
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1408674)
Ähemm, 3?

0..1000 oder irre ich mich? Wenns 0..999 ist, mein Fehler!

Okay okay, Herr Raabe hat natürlich mal wieder Recht, gerade mal nachgeschaut:
Zitat:

Valid millisecond values are 0 through 999.

DieDolly 25. Jul 2018 15:41

AW: Zeitcode
 
Ist mein Vorschlag somit hinfällig?

KodeZwerg 25. Jul 2018 15:45

AW: Zeitcode
 
Zitat:

Zitat von DieDolly (Beitrag 1408678)
Ist mein Vorschlag somit hinfällig?

Dein Vorschlag, wenn denn wirklich nach Millisekunden geforscht werden soll kann man per MilliSecondsBetween() berechnen.

DieDolly 25. Jul 2018 15:49

AW: Zeitcode
 
Da muss man dann aber In und Out erst nach TDateTime umrechnen, was bei einer zweistelligen Millisekunden-Angabe bei mir zu Fehlern führte.
TTimeSpan hingegen läuft durch.

himitsu 25. Jul 2018 15:50

AW: Zeitcode
 
Mit 4 ":" hab ich das auch noch nicht gesehn.

Und ob 2 oder 3 ist fast egal, da bei den meisten Formatierungen es als Fraction (Kommastellen an den Sekunden) dargestellt wird.

01:00
01:00:00
01:00:00.120

Und StrToTime kann sowas standardmäßig nicht richtig dekodieren.
Eventuell kann man es über StrToTime mit einem passenden FormatSetting für das LongTimeFormat ausgelesen bekommen,
aber die Date-/TimeFormate werden nur bedingt zum auslesen verwendet. (Designfehler)

Und Ja, Delphi nimmt vorwiegend nur 3-stellige Millisekunden (ZZZ)
Bei weniger als 3 Stellen muß man aufpassen, da es von fehlenden Leading-Zeros ausgeht.
http://docwiki.embarcadero.com/Libra...FormatDateTime

Dilom 25. Jul 2018 15:57

AW: Zeitcode
 
Stunden, Minuten, Sekunden, Rahmenberechnung


Hours, Minutes, seconds, frames - Hours, Minutes, seconds, frames = 01:00:00:00 :?::?::?:

KodeZwerg 25. Jul 2018 16:01

AW: Zeitcode
 
Zitat:

Zitat von DieDolly (Beitrag 1408680)
Da muss man dann aber In und Out erst nach TDateTime umrechnen

Input ist TDateTime, Output ist Int64.
Delphi-Quellcode:
function MilliSecondsBetween(const ANow, AThen: TDateTime): Int64;

DieDolly 25. Jul 2018 16:02

AW: Zeitcode
 
Sorry habe mich falsch ausgedrückt. Ich meinte natürlich die beiden Edits vom Themenersteller. Die nennt er/sie In und Out.

himitsu 25. Jul 2018 16:20

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408683)
Stunden, Minuten, Sekunden, Rahmenberechnung


Hours, Minutes, seconds, frames - Hours, Minutes, seconds, frames = 01:00:00:00 :?::?::?:

HH:MM:SS.Z (0..999 => 0..9, 10..99, 100..999)
HH:MM:SS.ZZZ (000..999)

also SS.ZZ ist SS.0ZZ (00.50 aka 50ms), aber nicht SS.ZZ0 (00.50 aka 500ms)


Wenn es etwas Anderes sein soll, dann kann TimeToStr, StrToTime, FormatDateTime und Co. nicht verwendet werden.
Maximal den "Frame" abtrennen, den Rest mir den Standardroutinen umrechnen und die Frames als Millisekunden nach/vor der Konvertierung dazurechnen/abziehen.

Delphi-Referenz durchsuchenSystem.SysUtils.FormatDateTime

KodeZwerg 25. Jul 2018 16:26

AW: Zeitcode
 
Mein Vorschlag an TE:
Ändere die Edit.Texte in dieses Format 00:00:00.000, danach sowas hier
Delphi-Quellcode:
function BerechneEditFelder ( S1, S2: String ): Int64;
var
  t1, t2: TDateTime;
begin
  try
    t1 := StrToTime( S1 );
    t2 := StrToTime( S2 );
  finally
    Result := MilliSecondsBetween ( t1, t2 );
  end;
end;
Das ergibt erstmal die Differenz in MilliSekunden. Sorry, nur QnD hier im Editor geschrieben = ungetestet.

Wie werden "Frames" bei Dir definiert?

edit
so hier Aufrufen falls das unklar ist:
Delphi-Quellcode:
Int64Dummy := BerechneEditFelder(Edit1.Text, Edit2.Text)


edit2
oder, um im TDateTime zu bleiben so hier
Delphi-Quellcode:
function BerechneEditFelder ( S1, S2: String ): TDateTime;
var
  t1, t2: TDateTime;
begin
  try
    t1 := StrToTime( S1 );
    t2 := StrToTime( S2 );
  finally
    Result := MilliSecondsBetween(t1, t2) / (1000.0 * 86400);
  end;
end;
Nun solltest Du die Differenz als TDateTime bequem abrufen können.

Dilom 25. Jul 2018 17:37

AW: Zeitcode
 
Zitat:

Zitat von KodeZwerg (Beitrag 1408687)
Mein Vorschlag an TE:
Ändere die Edit.Texte in dieses Format 00:00:00.000, danach sowas hier
Delphi-Quellcode:
function BerechneEditFelder ( S1, S2: String ): Int64;
var
  t1, t2: TDateTime;
begin
  try
    t1 := StrToTime( S1 );
    t2 := StrToTime( S2 );
  finally
    Result := MilliSecondsBetween ( t1, t2 );
  end;
end;
Das ergibt erstmal die Differenz in MilliSekunden. Sorry, nur QnD hier im Editor geschrieben = ungetestet.

Wie werden "Frames" bei Dir definiert?

edit
so hier Aufrufen falls das unklar ist:
Delphi-Quellcode:
Int64Dummy := BerechneEditFelder(Edit1.Text, Edit2.Text)


edit2
oder, um im TDateTime zu bleiben so hier
Delphi-Quellcode:
function BerechneEditFelder ( S1, S2: String ): TDateTime;
var
  t1, t2: TDateTime;
begin
  try
    t1 := StrToTime( S1 );
    t2 := StrToTime( S2 );
  finally
    Result := MilliSecondsBetween(t1, t2) / (1000.0 * 86400);
  end;
end;
Nun solltest Du die Differenz als TDateTime bequem abrufen können.




Delphi-Quellcode:
function BerechneEditFelder(S1, S2: String): TDateTime;
var
  t1, t2: TDateTime;
begin
  try
    t1 := StrToTime(S1);
    t2 := StrToTime(S2);
  finally
    result := MilliSecondsBetween(t1, t2) / (1000.0 * 86400);
  end;
end;


es gibt einen Fehler : Hata:: Hata:: Hata:: |
Delphi-Quellcode:
procedure TForm1.DurationClick(Sender: TObject);
begin
  Duration.Text := TimeToStr(BerechneEditFelder('01:00:00:00', '01:00:00:00'));
end;


in Ordnung : Başparmak:
Delphi-Quellcode:
procedure TForm1.PGDurationClick(Sender: TObject);
begin
  Duration.Text := TimeToStr(BerechneEditFelder('01:00:00', '01:00:00'));
end;

Redeemer 25. Jul 2018 18:01

AW: Zeitcode
 
No Google Translate on this website please. Programming with an English-based programming language doesn't make any sense if you don't speak English.

DieDolly 25. Jul 2018 18:04

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408689)
es gibt einen Fehler : Hata:: Hata:: Hata:: |
Delphi-Quellcode:
procedure TForm1.DurationClick(Sender: TObject);
begin
  Duration.Text := TimeToStr(BerechneEditFelder('01:00:00:00', '01:00:00:00'));
end;


in Ordnung : Başparmak:
Delphi-Quellcode:
procedure TForm1.PGDurationClick(Sender: TObject);
begin
  Duration.Text := TimeToStr(BerechneEditFelder('01:00:00', '01:00:00'));
end;

Die Millisekunden zu löschen, um keine Fehler mehr zu bekommen, sollte nicht die Lösung sein.

KodeZwerg 25. Jul 2018 18:29

AW: Zeitcode
 
FormatSettings hat gefehlt, so klappt es, ich habe es getestet mit Delphi 2009.
Delphi-Quellcode:
function GetMillisecondSpan(S1, S2: String): Int64;
var
  t1, t2: TDateTime;
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  try
    t1 := StrToTime(S1, FS);
    t2 := StrToTime(S2, FS);
  finally
    Result := MilliSecondsBetween(t1, t2);
  end;
end;

procedure TForm1.DurationClick(Sender: TObject);
begin
  Duration.Text := IntToStr(GetMillisecondSpan('01:23:45.678', '01:23:45.901'));
end;
In diesem Beispiel ist Duration.Text = 223

Delphi-Quellcode:
function GetDateTimeSpan ( S1, S2: String ): TDateTime;
var
  t1, t2: TDateTime;
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  try
    t1 := StrToTime(S1, FS);
    t2 := StrToTime(S2, FS);
  finally
    Result := MilliSecondsBetween(t1, t2) / (1000.0 * 86400);
  end;
end;

procedure TForm1.DurationClick(Sender: TObject);
var
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  Duration.Text := TimeToStr(GetDateTimeSpan('01:23:45.678','01:23:45.901'), FS);
end;
In diesem Beispiel ist Duration.Text = 00:00:00.223

Ich hoffe nun ist dieser Thread zufriedenstellend erledigt.

p80286 25. Jul 2018 19:07

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408683)
Stunden, Minuten, Sekunden, Rahmenberechnung


Hours, Minutes, seconds, frames - Hours, Minutes, seconds, frames = 01:00:00:00 :?::?::?:

Das erinnert mich an die gute alte Audio-CD.
Zitat:

The track positions are referenced by absolute timecode, relative to the start of the program area, in MSF format: minutes, seconds, and fractional seconds called frames. Each timecode frame is one seventy-fifth of a second, and corresponds to a block of 98 channel-data frames
Näheres hier

Gruß
K-H

KodeZwerg 26. Jul 2018 06:35

AW: Zeitcode
 
Zitat:

Zitat von p80286 (Beitrag 1408694)
Näheres hier

Habe mir das mal durchgelesen mit den Frames (ich pers. kenne Frames nur von Video-Inhalten bzw Video-Schnitt-Tools), selbst bei CD scheint es da zwei verschiedene Frame-Berechnungen zu geben.

himitsu 26. Jul 2018 09:36

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408689)
es gibt einen Fehler : Hata:: Hata:: Hata::

Ja, nur ist der Fehler, dass jemand vergisst den Fehler zu nennen.

Strg+C in Dialogen und Strg+V hier im Texteditor helfen, wenn man nocht abschreiben oder auf den Monitor schießen möchte.


Und ansonsten hatte ich schon alles gesagt, was die "Frames" oder sonstwas betrifft, welches keine Millisekunden sind, sowie zum Format der Datums-String.

Dilom 26. Jul 2018 14:40

AW: Zeitcode
 
Zitat:

Zitat von KodeZwerg (Beitrag 1408693)
FormatSettings hat gefehlt, so klappt es, ich habe es getestet mit Delphi 2009.
Delphi-Quellcode:
function GetMillisecondSpan(S1, S2: String): Int64;
var
  t1, t2: TDateTime;
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  try
    t1 := StrToTime(S1, FS);
    t2 := StrToTime(S2, FS);
  finally
    Result := MilliSecondsBetween(t1, t2);
  end;
end;

procedure TForm1.DurationClick(Sender: TObject);
begin
  Duration.Text := IntToStr(GetMillisecondSpan('01:23:45.678', '01:23:45.901'));
end;
In diesem Beispiel ist Duration.Text = 223

Delphi-Quellcode:
function GetDateTimeSpan ( S1, S2: String ): TDateTime;
var
  t1, t2: TDateTime;
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  try
    t1 := StrToTime(S1, FS);
    t2 := StrToTime(S2, FS);
  finally
    Result := MilliSecondsBetween(t1, t2) / (1000.0 * 86400);
  end;
end;

procedure TForm1.DurationClick(Sender: TObject);
var
  FS: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
  FS.DecimalSeparator := '.';
  FS.TimeSeparator := ':';
  FS.LongTimeFormat := 'hh:nn:ss.zzz';
  Duration.Text := TimeToStr(GetDateTimeSpan('01:23:45.678','01:23:45.901'), FS);
end;
In diesem Beispiel ist Duration.Text = 00:00:00.223

Ich hoffe nun ist dieser Thread zufriedenstellend erledigt.



Danke. : Başparmak:

KodeZwerg 26. Jul 2018 17:12

AW: Zeitcode
 
Zitat:

Zitat von Dilom (Beitrag 1408776)
Danke. : Başparmak:

Bitte.

Uwe Raabe 26. Jul 2018 17:38

AW: Zeitcode
 
Jetzt möchte ich aber doch schon noch wissen, wie lang so ein Frame denn nun ist bzw. wie viele es davon in einer Sekunde gibt.

p80286 26. Jul 2018 22:39

AW: Zeitcode
 
75 Frames sollten 1 sec sein wenn ich mich recht erinnere.

Başparmak = :thumb:


Gruß
K-H

Uwe Raabe 26. Jul 2018 23:02

AW: Zeitcode
 
Zitat:

Zitat von p80286 (Beitrag 1408819)
75 Frames sollten 1 sec sein wenn ich mich recht erinnere

Dann kann man aber den Frame-Wert nicht einfach als Millisekunden interpretieren, weder mit führender noch mit angehängter 0. Zumindest wird das hier suggeriert:
Zitat:

Ändere die Edit.Texte in dieses Format 00:00:00.000,
Ausgehend vom ersten Post, was soll denn bei 00:00:01:11 - 00:00:00:12 herauskommen? Nach meinem Verständnis müsste das 00:00:00:74 sein.

Je nach Interpretation der Frames als Milli- oder Zentisekunden kommt da aber 00:00:00.999 oder 00:00:00.990 raus. Nur wenn man die Frames vorher in 1/75 Sekunden umrechnet passt das Ergebnis - bis auf die dabei entstehenden Rundungsfehler.

KodeZwerg 27. Jul 2018 05:35

AW: Zeitcode
 
Nur wenn Frames sich auf Audio-CD bezieht. Schaut mal hier: Frames per second ↔ Frames per millisecond Conversion

p80286 27. Jul 2018 07:19

AW: Zeitcode
 
Da wir nicht wissen in welchem Kontext die Frage steht, sind alle "Lösungen" spekulativ.

Gruß
K-H

samso 27. Jul 2018 07:49

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:
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.
Ausgabe
+02:00:00:00
+01:59:59:74

Uwe Raabe 27. Jul 2018 07:57

AW: Zeitcode
 
Zitat:

Zitat von KodeZwerg (Beitrag 1408827)
Nur wenn Frames sich auf Audio-CD bezieht. Schaut mal hier: Frames per second ↔ Frames per millisecond Conversion

Und wo kann ich in dem Link sehen, wie lang ein Frame ist? Für die Erkenntnis, daß 1 Frame pro Sekunde gleich 1/1000 Frame pro Millisekunde ist, brauche ich weder einen Taschenrechner noch ein Javascript Applet. Leider bringt die Seite aber immer noch keine Antwort auf die Frage wie man Frames in Millisekunden umrechnet.

KodeZwerg 27. Jul 2018 08:11

AW: Zeitcode
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1408831)
Und wo kann ich in dem Link sehen, wie lang ein Frame ist? Für die Erkenntnis, daß 1 Frame pro Sekunde gleich 1/1000 Frame pro Millisekunde ist, brauche ich weder einen Taschenrechner noch ein Javascript Applet. Leider bringt die Seite aber immer noch keine Antwort auf die Frage wie man Frames in Millisekunden umrechnet.

Bei Videospielen wäre die Antwort "FPS = Soviel Bilder wie in einer Sekunde dargestellt werden können (CPU/GPU abhängig)"
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 von KodeZwerg (Beitrag 1408687)
Wie werden "Frames" bei Dir definiert?

bzw
Zitat:

Zitat von Uwe Raabe (Beitrag 1408801)
Jetzt möchte ich aber doch schon noch wissen, wie lang so ein Frame denn nun ist bzw. wie viele es davon in einer Sekunde gibt.


Zitat:

Zitat von p80286 (Beitrag 1408829)
Da wir nicht wissen in welchem Kontext die Frage steht, sind alle "Lösungen" spekulativ.

Da TE seinen Daumen gab, betrachte ich es als erledigt.

KodeZwerg 27. Jul 2018 09:34

AW: Zeitcode
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von samso (Beitrag 1408830)
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.

Interessanter Code, Danke dafür.
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.

samso 27. Jul 2018 09:47

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.

KodeZwerg 27. Jul 2018 09:55

AW: Zeitcode
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke an samso, Anhang angepasst für ältere Delphis.

Uwe Raabe 27. Jul 2018 09:56

AW: Zeitcode
 
Zitat:

Zitat von samso (Beitrag 1408840)
Wenn man gleich mit fps arbeitet, wird es einfacher (man bekommt aber auch früher einen Überlauf (ab so rund 16000h)

Dann nimm doch
Delphi-Quellcode:
Int64
.

samso 27. Jul 2018 10:08

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 07:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz