{"id":16102378,"url":"https://github.com/sshaw/time-timecode","last_synced_at":"2025-07-27T03:04:46.063Z","repository":{"id":881412,"uuid":"626477","full_name":"sshaw/Time-Timecode","owner":"sshaw","description":"Video timecode class for Perl and command line program. Supports any frame rate, conversions, drop/non-drop frame counts and more. ","archived":false,"fork":false,"pushed_at":"2020-01-09T00:21:32.000Z","size":40,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-01T18:45:08.407Z","etag":null,"topics":["conversion","drop-frames","ffmpeg","frame-rate","perl","smpte-timecode","timecode","video","video-timecode-manipulation"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshaw.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-04-24T06:15:29.000Z","updated_at":"2023-03-14T09:18:51.000Z","dependencies_parsed_at":"2022-07-18T14:47:33.370Z","dependency_job_id":null,"html_url":"https://github.com/sshaw/Time-Timecode","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2FTime-Timecode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2FTime-Timecode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2FTime-Timecode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2FTime-Timecode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshaw","download_url":"https://codeload.github.com/sshaw/Time-Timecode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229805745,"owners_count":18126902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conversion","drop-frames","ffmpeg","frame-rate","perl","smpte-timecode","timecode","video","video-timecode-manipulation"],"created_at":"2024-10-09T18:53:41.503Z","updated_at":"2024-12-17T00:42:43.862Z","avatar_url":"https://github.com/sshaw.png","language":"Perl","readme":"=pod\n\n=encoding UTF-8\n\n=head1 NAME\n\nTime::Timecode - Video timecode class and command line program\n\n=for html \u003ca href=\"https://travis-ci.org/sshaw/Time-Timecode\"\u003e\u003cimg src=\"https://travis-ci.org/sshaw/Time-Timecode.svg?branch=master\"\u003e\u003c/a\u003e\n\n=head1 SYNOPSIS\n\nTo install the C\u003ctimecode\u003e executable see L\u003c/TIMECODE UTILITY PROGRAM\u003e.\n\nTo use with your Perl program:\n\n use Time::Timecode;\n\n my $tc1 = Time::Timecode-\u003enew(2, 0, 0, 12); # hh, mm, ss, ff\n print $tc1-\u003efps;                            # $DEFAULT_FPS\n print $tc1;                                 # 02:00:00:12\n print $tc1-\u003ehours;                          # 2\n print $tc1-\u003ehh;                             # shorthanded version\n print $tc1-\u003eto_string('%Hh%Mm%Ss%ff')       # 2h0m0s12f\n\n my $tc2 = Time::Timecode-\u003enew('00:10:30:00', { fps =\u003e 25 } );\n print $tc2-\u003etotal_frames;                   # 15750\n print $tc2-\u003efps;                            # 25\n\n $tc2 = Time::Timecode-\u003enew(1800);           # Total frames\n print $tc1 + $tc2;                          # 02:01:00:12\n\n $tc1 = Time::Timecode-\u003enew('00:01:00;04');  # Dropframe (see the \";\")\n print $tc1-\u003eis_dropframe;                   # 1\n\n my $diff = $tc1 - 1800;                     # Subtract 1800 frames\n print $tc1-\u003eis_dropframe;                   # 1, maintains LHS' options\n print $diff;                                # 00:00:02;00\n\n # Conversions\n my $pal  = $tc-\u003econvert(25);\n my $ntsc = $pal-\u003econvert(30), { dropframe =\u003e 1 });\n my $ndf  = $ntsc-\u003eto_non_dropframe;\n\n my $opts = { delimiter =\u003e ',', frame_delimiter =\u003e '+' };\n $Time::Timecode::DEFAULT_FPS = 23.976;\n $tc2 = Time::Timecode-\u003enew('00,10,30+00', $opts);\n print $tc2-\u003efps                             # 23.976\n print $tc2-\u003eminutes;                        # 10\n print $tc2-\u003eseconds;                        # 30\n\n=head1 DESCRIPTION\n\nC\u003cTime::Timecode\u003e supports SMTPE timecodes, any frame rate,\ndrop/non-drop frame counts, basic arithmetic, and conversion between\nframe rates and drop/non-drop frame counts. The only requirements are\nthat the timecode be between 00:00:00:00 and 99:99:99:99, inclusive,\nand frames per second (fps) are greater than zero. This means that you\ncan create nonstandard timecodes (feature or bug?). Dropframe rules\nwill still apply.\n\nC\u003cTime::Timecode\u003e instances can be created from a a variety of representations,\nsee L\u003c/CONSTRUCTOR\u003e.\n\nC\u003cTime::Timecode\u003e instances are immutable.\n\n=head1 CONSTRUCTOR\n\n=over 2\n\n=item C\u003cnew( TIMECODE [, OPTIONS ] )\u003e\n\nCreates an immutable instance for C\u003cTIMECODE\u003e with the given set of C\u003cOPTIONS\u003e.\nIf no C\u003cOPTIONS\u003e are given L\u003cthe package defaults|/DEFAULTS\u003e are used.\n\n=back\n\n=head2 TIMECODE\n\nC\u003cTIMECODE\u003e can be one of the following:\n\n=over 4\n\n=item * A list denoting hours, minutes, seconds, and/or frames:\n\n $tc1 = Time::Timecode-\u003enew(1, 2, 3)\n $tc1 = Time::Timecode-\u003enew(1, 2, 3, 0)   #same as above\n\n=item * Frame count:\n\n $tc1 = Time::Timecode-\u003enew(1800)   # 00:01:00:00 @ 30 fps\n\n=item * Timecode string:\n\n $tc1 = Time::Timecode-\u003enew('00:02:00:25')\n\nB\u003cTimecode strings with dropframe frame delimiters\u003e\n\nIn the video encoding world timecodes with a frame delimiter of \".\" or \";\" are considered\ndropframe. If either of these characters are used in the timecode string passed to C\u003cnew\u003e\nthe resulting instance will dropframe.\n\nThis can be overridden by setting L\u003cthe dropframe argument|/* dropframe\u003e to false.\n\n=back\n\n=head2 OPTIONS\n\nC\u003cOPTIONS\u003e must be a hash reference and can contain any of the following:\n\n=over 4\n\n=item * fps:\n\nFrames per second, must be greater than 0. Defaults to C\u003c$Time::Timecode::DEFAULT_FPS\u003e\n\n=item * dropframe:\n\nA boolean value denoting wheather or not the timecode\nis dropframe. Defaults to C\u003c$Time::Timecode::DEFAULT_DROPFRAME\u003e.\n\n=item * delimiter:\n\nThe character used to delimit the timecode's hours, minutes,\nand seconds. Use L\u003cthe frame_delimiter option|/* frame_delimiter\u003e for delimiting the frames.\nDefaults to C\u003c$Time::Timecode::DEFAULT_DELIMITER\u003e.\n\n=item * frame_delimiter:\n\nThe character used to delimit the timecode's frames.\nUse L\u003cthe delimiter option|/* delimiter\u003e for delimiting the rest of the timecode.\nDefaults to C\u003c$Time::Timecode::DEFAULT_FRAME_DELIMITER\u003e.\n\n=back\n\n=head1 METHODS\n\nAll time part accessors return an integer except C\u003cframes\u003e which, depending on the\nframe rate, can return a float.\n\n=over 2\n\n=item C\u003chours\u003e\n\n=item C\u003chrs\u003e\n\n=item C\u003chh\u003e\n\nReturns the hour part of the timecode\n\n=item C\u003cminutes\u003e\n\n=item C\u003cmins\u003e\n\n=item C\u003cmm\u003e\n\nReturns the mintue part of the timecode\n\n=item C\u003cseconds\u003e\n\n=item C\u003csecs\u003e\n\n=item C\u003css\u003e\n\nReturns the second part of the timecode\n\n=item C\u003cframes\u003e\n\n=item C\u003cff\u003e\n\nReturns the frame part of the timecode\n\n=item C\u003cfps\u003e\n\nReturns the frames per second\n\n=item C\u003ctotal_frames\u003e\n\nReturns the timecode in frames\n\n=item C\u003cto_string([FORMAT])\u003e\n\nReturns the timecode as string described by C\u003cFORMAT\u003e. If C\u003cFORMAT\u003e is not provided the\nstring will be constructed according to the L\u003cinstance's defaults|/DEFAULTS\u003e.\n\n  $tc = Time::Timecode-\u003enew(2,0,10,24);\n  $tc-\u003eto_string\t\t\t# 02:00:10:24\n  \"$tc\"\t\t\t\t\t# Same as above\n  $tc-\u003eto_string('%02H%02M%S.%03f DF')\t# 020010.024 DF\n\nC\u003cFORMAT\u003e is string of characters synonymous (mostly, in some way) with\nthose used by C\u003c\u003c strftime(3) \u003e\u003e, with the exception that no leading zero will be added\nto single digit values. If you want leading zeros you must specify a field width like\nyou would with C\u003c\u003c printf(3) \u003e\u003e.\n\nThe following formats are supported:\n\n%H B\u003cH\u003eours\n\n%M B\u003cM\u003einutes\n\n%S B\u003cS\u003eeconds\n\n%f B\u003cf\u003erames\n\n%i B\u003ci\u003en frames (i.e., C\u003c\u003c $tc-\u003etotal_frames \u003e\u003e)\n\n%r Frame B\u003cr\u003eate\n\n%s Frames as a fraction of a second\n\n%T B\u003cT\u003eimecode in the L\u003cinstance's default format|/DEFAULTS\u003e.\n\n%% Literal percent character\n\nWhen applicable, formats assume the width of the number they represent.\n\nIf a C\u003cFORMAT\u003e is not provided the delimiter used to separate each portion of the timecode can vary.\nIf the C\u003cdelimiter\u003e or C\u003cframe_delimiter\u003e options were provided they will be used here.\nIf the timecode was created from a timecode string that representation will be reconstructed.\n\nThis method is overloaded and will be called when an instance is quoted. I.e., C\u003c\u003c \"$tc\" eq $tc-\u003eto_string \u003e\u003e\n\n=item C\u003cis_dropframe\u003e\n\nReturns a boolean value denoting whether or not the timecode is dropframe.\n\n=item C\u003cto_non_dropframe\u003e\n\nConverts the timecode to non-dropframe and returns a new C\u003cTime::Timecode\u003e instance.\nThe framerate is not changed.\n\nIf the current timecode is non-dropframe C\u003c$self\u003e is returned.\n\n=item C\u003cto_dropframe\u003e\n\nConverts the timecode to dropframe and returns a new C\u003cTime::Timecode\u003e instance.\nThe framerate is not changed.\n\nIf the current timecode is dropframe C\u003c$self\u003e is returned.\n\n=item C\u003cconvert( FPS [, OPTIONS ] )\u003e\n\nConverts the timecode to C\u003cFPS\u003e and returns a new instance.\n\nC\u003cOPTIONS\u003e are the same as L\u003cthose allowed by the CONSTRUCTOR|/OPTIONS\u003e. Any unspecified options\nwill be taken from the calling instance.\n\nThe converted timecode will be non-dropframe.\n\n=back\n\n=head1 ARITHMETIC \u0026 COMPARISON\n\nArithmatic and comparison are provided via operator overloading. When applicable results get\nL\u003ctheir options|/OPTIONS\u003e from the left hand side (LHS) of the expression. If the LHS is a\nliteral the options will be taken from the right hand side.\n\n=head2 Supported Operations\n\n=head3 Addition\n\n  $tc1 = Time::Timecode-\u003enew(1800);\n  $tc2 = Time::Timecode-\u003enew(1);\n  print $tc1 + $tc2;\n  print $tc1 + 1800;\n  print 1800 + $tc1;\n  print $tc1 + '00:10:00:00';\n\n=head3 Subtraction\n\n  $tc1 = Time::Timecode-\u003enew(3600);\n  $tc2 = Time::Timecode-\u003enew(1);\n  print $tc1 - $tc2;\n  print $tc1 - 1800;\n  print 1800 - $tc1;\n  print $tc1 - '00:00:02:00';\n\n=head3 Multiplication\n\n  $tc1 = Time::Timecode-\u003enew(1800);\n  print $tc1 * 2;\n  print 2 * $tc1;\n\n=head3 Division\n\n  $tc1 = Time::Timecode-\u003enew(1800);\n  print $tc1 / 2;\n\n=head3 Pre/postincrement with/without assignment\n\n  $tc1 = Time::Timecode-\u003enew(1800);\n  $tc1 += 10;\t\t# Add 10 frames\n  print ++$tc1;\t\t# Add 1 frame\n  print $tc1--;\t\t# Subtract it after printing\n\n=head3 All comparison operators\n\n  $tc1 = Time::Timecode-\u003enew(1800);\n  $tc2 = Time::Timecode-\u003enew(1800);\n  print 'equal!' if $tc1 == $tc2;\n  print 'less than' if $tc1 \u003c '02:00:12;22';\n  print 'greater than' if $tc1 \u003e= '02:00:12;22';\n  # ....\n\n=head1 DEFAULTS\n\nAll defaults except C\u003c$DEFAULT_TO_STRING_FORMAT\u003e can be overridden when L\u003ccreating a new instance|/CONSTRUCTOR\u003e.\nC\u003c$DEFAULT_TO_STRING_FORMAT\u003e can be overridden by passing a format to C\u003c\u003c L\u003cto_string|/to_string([FORMAT])\u003e \u003e\u003e.\n\nC\u003c$DEFAULT_FPS = 29.97\u003e\n\nC\u003c$DEFAULT_DROPFRAME = 0\u003e\n\nC\u003c$DEFAULT_DELIMITER = ':'\u003e\n\nC\u003c$DEFAULT_FRAME_DELIMITER = ':'\u003e\n\nC\u003c$DEFAULT_TO_STRING_FORMAT = 'HHxMMxSSxFF'\u003e  where C\u003cx\u003e represents the instance's frame and time separators.\n\n=head1 TIMECODE UTILITY PROGRAM\n\nC\u003cTime::Timecode\u003e includes an executable called C\u003ctimecode\u003e that allows one to perform timecode conversions\nand arithmetic.\n\nUsing it requires L\u003cPerl|https://www.perl.org/get.html\u003e. Once Perl is installed run the following command to\ninstall it: C\u003ccpan Time::Timecode\u003e\n\n=head2 Usage\n\n  usage: timecode [-h] [-c spec] [-f format] [-i spec] [expression]\n      -h --help\t\t   option help\n      -c --convert spec      convert expression according to `spec'\n                             `spec' can be a number of FPS proceeded by an optional `D', `ND', `DF' or\n                             a comma separated list of key=value.\n                             key can be fps, dropframe, delimiter, frame_delimiter\n      -f --format  format    output timecode according to `format' e.g., '%H:%M:%S at %r FPS'.\n                             %H=hours, %M=mins, %S=secs, %f=frames, %i=total frames, %r=frame rate,\n                             %s=frames in secs\n      -i --input   spec      process incoming expressions according to `spec'; see -c for more info\n      -q --quiet             ignore invalid expressions\n      -v --version           print version information\n\n  Expression can be a timecode, a number of frames, or an arithmetic expression composed one or both.\n  If no expression is given timecode will read from stdin.\n\n=head2 Examples\n\n=head3 Convert frames to a 29.97 dropframe timecode\n\n  timecode -c 29.97df 1800\n  00:01:00:02\n\n=head3 Convert 24 to 29.97 dropframe and output the result as frames\n\n  timecode -i 24 -c 29.97df -f %i 00:12:33:19\n  18091\n\n=head3 Subtract two dropframe timecodes\n\n  timecode -c 29.97 23:00:04.29-00:00:05.00\n  22:58:37.05\n\n=head3 Convert a list of timecodes from a file to a custom format, ignoring invalid timecodes\n\n  cat \u003e /tmp/times.txt\n  02:01:00:12\n  foo!\n  02:02:21:00\n  02:01:00:02\n\n  timecode -qi 24 -f '%Hh %Mm %Ss and %f frames' \u003c /tmp/times.txt\n  02:01:00:12 2h 1m 0s and 12 frames\n  02:02:21:00 2h 2m 21s and 0 frames\n  02:01:00:02 2h 1m 0s and 2 frames\n\n=head1 SEE ALSO\n\n=over 2\n\n=item L\u003c\u003c C\u003cTime::Timecode source code\u003e|https://github.com/sshaw/Time-Timecode \u003e\u003e\n\n=item L\u003cxslt-timecode|https://github.com/sshaw/xslt-timecode\u003e - A pure, dependency free, XSLT 1.0 library for video timecode manipulation\n\n=item L\u003ciTunes Store Transporter: GUI|http://transportergui.com\u003e - GUI and workflow automation for the iTunes Store’s Transporter (iTMSTransporter)\n\n=back\n\n=head1 AUTHOR\n\nMade by L\u003cScreenStaring|http://screenstaring.com\u003e.\n\n=head1 CREDITS\n\nJinha Kim for schooling me on dropframe timecodes.\n\nL\u003cAndrew Duncan|http://andrewduncan.net/\u003e (and L\u003cDavid Heidelberger|http://www.davidheidelberger.com/\u003e)\nfor the L\u003cnice drop frame algorithm|http://www.davidheidelberger.com/blog/?p=29\u003e.\n\n=head1 REFERENCES\n\nFor information about dropframe timecodes see:\nL\u003chttp://andrewduncan.net/timecodes/\u003e, L\u003chttp://dropframetimecode.org/\u003e, L\u003chttp://en.wikipedia.org/wiki/SMPTE_time_code#Drop_frame_timecode\u003e\n\n=head1 COPYRIGHT\n\nCopyright (c) 2009-2018 Skye Shaw. All rights reserved.\n\n=head1 LICENSE\n\nThis program is free software; you can redistribute it and/or modify it under the\nsame terms as Perl itself.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaw%2Ftime-timecode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshaw%2Ftime-timecode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaw%2Ftime-timecode/lists"}