Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
TimeCode (TC) Struct für Videobearbeitung
jaensen
myCSharp.de - Experte

Avatar #avatar-2657.png


Dabei seit:
Beiträge: 2885
Herkunft: München

Themenstarter:

TimeCode (TC) Struct für Videobearbeitung

beantworten | zitieren | melden

Beschreibung:

Eine C# Implementierung des Timecode welcher bei der Videobearbeitung verwendet wird.

Methoden:
- ToString: Gibt den Timecode im Format HH:MM:SS:FF aus
- FromMilliseconds: Erstellt eine Timecode Instanz aus der Anzahl der Millisekunden und den FPS
- FromTimeSpan: Erstellt eine Timecode Instanz aus einem Timespan objekt und den FPS
- CalculateDuration: Berechnet die Dauer aus TcIn und TcOut
- Parse: Erstellt eine MediaTimeCode Instanz aus einem String im Format HH:MM:SS:FF


public struct MediaTimeCode {

        public int Hours { get; set; }
        public int Minutes { get; set; }
        public int Seconds { get; set; }
        public int Frames { get; set; }

        public static MediaTimeCode FromMilliseconds(long milliseconds, int framesPerSecond) {

            TimeSpan timespan = TimeSpan.FromMilliseconds(milliseconds);

            return FromTimeSpan(timespan, framesPerSecond);
        }

        public static MediaTimeCode FromTimeSpan(TimeSpan timespan, int framesPerSecond) {

            double framesPerMillisecond = (double)framesPerSecond / (double)1000;
            int frames = (int)(timespan.Milliseconds * framesPerMillisecond);

            return new MediaTimeCode() {
                Hours = timespan.Hours,
                Minutes = timespan.Minutes,
                Seconds = timespan.Seconds,
                Frames = frames
            };
        }

        public static MediaTimeCode CalculateDuration(MediaTimeCode tcIn, MediaTimeCode tcOut, int fps) {

            double fpm = 60 * fps;
            double fph = 60 * fpm;

            double frameHours = tcIn.Hours * fph;
            double frameMinutes = tcIn.Minutes * fpm;
            double frameSeconds = tcIn.Seconds * fps;

            double tcInFrames = frameHours + frameMinutes + frameSeconds + tcIn.Frames;

            frameHours = tcOut.Hours * fph;
            frameMinutes = tcOut.Minutes * fpm;
            frameSeconds = tcOut.Seconds * fps;

            double tcOutFrames = frameHours + frameMinutes + frameSeconds + tcOut.Frames;

            double durationInFrames = tcOutFrames - tcInFrames;

            int fRest = (int)durationInFrames % (int)fps;
            int frames = (int)durationInFrames - fRest;

            int s = frames / (int)fps;
            int sRest = s % 60;
            int minutes = ((s - sRest) / 60) % 60;
            int hours = (100 - minutes) / 60;

            return new MediaTimeCode() {
                Hours = hours,
                Minutes = minutes,
                Seconds = sRest,
                Frames = fRest
            };
        }

        public override string ToString() {
            return string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                Hours,
                Minutes,
                Seconds,
                Frames);
        }

        public static MediaTimeCode Parse(string tcString) {

            string[] tcParts = tcString.Split(':');

            int hours = int.Parse(tcParts[0]);
            int minutes = int.Parse(tcParts[1]);
            int seconds = int.Parse(tcParts[2]);
            int frames = int.Parse(tcParts[3]);

            return new MediaTimeCode() {
                Hours = hours,
                Minutes = minutes,
                Seconds = seconds,
                Frames = frames
            };
        }
    }

Schlagwörter: Video Timecode, TcIn, TcOut, Struct
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von jaensen am .
private Nachricht | Beiträge des Benutzers
t2t
myCSharp.de - Member



Dabei seit:
Beiträge: 436
Herkunft: Hamburg

beantworten | zitieren | melden

Hi jaensen,

erstmal Danke für deine Timecode Komponente. Die hat mir ein gutes Stück Arbeit abgenommen. Mir ist nur aufgefallen, dass die Duration Berechnung nicht ganz korrekt hinhaut.

Beispielsweise bei einem Input von
tcIn = 01:00:00:00
tcOut = 01:00:33:00
FrameBase = 24

Erhalte ich ein Output von 01:00:33:00
Würde aber ein Output von 00:00:33:00 erwarten

Da ich deine Berechnung nicht ganz nachvollziehen kann und sehr schnell ein Ergebnis brauchte, habe ich zu einer Quick & Dirty Lösung gegriffen.

Dazu habe ich die durationInFrames in Millisekunden umgerechnet. Bei einer FrameBase von 24 dauert ein Frame 41.666666667 ms. Also habe ich folgendes berechnet:


TimeSpan t = TimeSpan.FromMilliseconds(durationInFrames * 41.666666667);

dann habe ich einfach aus der TimeSpan wieder den TimeCode herausgezogen:


return new MediaTimeCode()
{
     Hours = t.Hours,
     Minutes = t.Minutes,
     Seconds = t.Seconds,
     Frames = (int)Math.Round(t.Milliseconds / 41.666666667, MidpointRounding.AwayFromZero)
};

Wie sauber dies nun in jedem erdenklichen Fall funktioniert, das kann ich auf die schnelle nicht sagen (Stichwort eventuelle Rundungsfehler). Die Berechnung meiner Timeline konnte ich damit aber bisher fehlerfrei umsetzen.
private Nachricht | Beiträge des Benutzers
Section31
myCSharp.de - Member



Dabei seit:
Beiträge: 65
Herkunft: Leipzsch

beantworten | zitieren | melden

Hallo,

ich denke mal, der Abschnitt


    int s = frames / (int)fps;
    int sRest = s % 60;
    int minutes = ((s - sRest) / 60) % 60;
    int hours = (100 - minutes) / 60;

in der Funktion CalculateDuration müsste eher wie folgt lauten:


    int s = frames / (int)fps;
    int sRest = s % 60;
    int minutes = (s / 60) % 60;
    int hours = s / 3600;


Grüße
Maik
private Nachricht | Beiträge des Benutzers
alexanderschill
myCSharp.de - Member



Dabei seit:
Beiträge: 57

beantworten | zitieren | melden

Wieso denn immer das Rad neu erfinden statt einfachd as bestehende zu erweitern:


using System;
public static class MediaTimeCode
{
    public static int TotalFrames(this TimeSpan TimeCode, int FPS)
    {
        return (int)((FPS / 1000D) * TimeCode.TotalMilliseconds);
    }

    public static int Frame(this TimeSpan TimeCode, int FPS)
    {
        return (int)((FPS / 1000D) * TimeCode.Milliseconds);
    }

    public static String ToMediaTimeCode(this TimeSpan TimeCode, int FPS)
    {
        return String.Format("{0:T}:{1}", TimeCode, TimeCode.Frame(FPS));
    }
}

das fügt dem TimeSpan struct einafch eine Frame methode hin zu und sollte ziemlich denselben effekt wie dein struct haben :)

außerdem lässt sich so weiter mit TimeSpans arbeiten die in manchen hinsichten besser sind
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von alexanderschill am .
Gruß Alexander Schill
private Nachricht | Beiträge des Benutzers