Video Time Codes for Ruby
Something I needed for a recent project to handle converting SMPTE codes to frame numbers and back again. I am using this with FFMpeg to generate thumbnails and editted clips based upon hand entered time codes.
The PAL and DV settings have not been tested. And this has only been used in the context of one project. So your mileage may vary.
It uses a format compatible with ffmpeg:
hh:mm:ss[.xxx] were .xxx is a percentage of a second.
Example SMPTECodes.standard= :pal #=> :pal SMPTECodes.fps #=> 25.0 t = "95:33:24.92" #=> "95:33:24.92" t.to_frame #=> 8256118 t.to_frame.to_smpte #=> "95:33:24.92" t == t.to_frame.to_smpte #=> true SMPTECodes.standard= :ntsc #=> :ntsc SMPTECodes.fps #=> 29.97002997003 t = "95:33:24.70" #=> "95:33:24.70" t.to_frame #=> 10309831 t.to_frame.to_smpte #=> "95:33:24.70" t == t.to_frame.to_smpte #=> true
class SMPTECodes
#http://en.wikipedia.org/wiki/SMPTE_timecode
@@standard = :ntsc
def self.standard
@@standard
end
# Set the frequency standard, ie :ntsc, :pal, :dv
def self.standard=(code)
@@standard = code
end
def self.fps
case self.standard
when :ntsc: 30/1.001
when :pal: 25.0
when :dv: 30.0
end
end
module String
# Converts an SMPTE code into a frame number based upon the current FPS
def to_frame
t = self.split(/:|\./).map {|i| i.to_i}
while t.length < 4 do
t.insert 0, 0
end
# hours(?):Miutes:seconds.frames
((t[0]*(60*60*SMPTECodes.fps)) +
(t[1]*(60*SMPTECodes.fps)) +
(t[2] * SMPTECodes.fps) +
( (t[3].to_f*(SMPTECodes.fps/100)).round)).round
end
end
module Numeric
# Converts an a frame number to an SMPTE string
def to_smpte
h, m = self.divmod(60 * 60* SMPTECodes.fps)
m, s = m.divmod(60* SMPTECodes.fps)
s, f = (s).divmod(SMPTECodes.fps)
f = (f.round*(100.0/SMPTECodes.fps))
if f >= 100
s = s+1;
f = 0;
end
"#{("%02d" % h.round)}:#{("%02d" % m.round)}:#{("%02d" % s.round)}.#{("%02d" % f.round)}"
end
end
end
# Mixin the modules
String.send :include, SMPTECodes::String
Numeric.send :include, SMPTECodes::Numeric