I'm new to Ruby so I'm probably going about this completely wrong, but using taglib-ruby
I keep getting a wrong result unless it's a wrong amount of seconds maybe nanoseconds?
I tried with bash
and mediainfo a different movie but worked ok ...
$(date -ud "@$(($seconds/1000))" +'%_H:%M')
def get_duration_hrs_and_mins(milliseconds)
return '' unless milliseconds
hours, milliseconds = milliseconds.divmod(1000 * 60 * 60)
minutes, milliseconds = milliseconds.divmod(1000 * 60)
seconds, milliseconds = milliseconds.divmod(1000)
"#{hours}h #{minutes}m #{seconds}s #{milliseconds}ms"
end
TagLib::MP4::File.open("filename.mp4") do |mp4|
seconds = mp4.length
puts get_duration_hrs_and_mins(seconds)
end
The amount of seconds is 1932993085 and the duration should be roughly 2 h 15 min.
I'm afraid you are misinformed. The length
attribute of a TagLib::MP4::File
object is inherited from the regular File
class and just tells you the size of the file in bytes; it has nothing to do with the duration of the contained media:
$ ls -l test.mp4
-rw-r--r--@ 1 user staff 39001360 Aug 14 2015 test.mp4
$ ruby -rtaglib -e 'TagLib::MP4::File.open("test.mp4"){|f|puts f.length}'
39001360
The particular file I'm examining in the above code snippet happens to be 25 seconds long, but there's no way to tell that from the fact that it's about 39 megabytes in size.
What you want is the #length
method of the TagLib::MP4::Properties
object, not the ::File
one. You can get that by calling #audio_properties
on the File object:
TagLib::MP4::File.open("filename.mp4") do |mp4|
seconds = mp4.audio_properties.length
puts get_duration_hrs_and_mins(seconds)
end
That return value is seconds, not milliseconds, so you need to adjust your get_duration
method accordingly. Really you just want something like this:
total_seconds = mp4.audio_properties.length
total_minutes, seconds = total_seconds.divmod(60)
total_hours, minutes = total_minutes.divmod(60)
days, hours = total_hours.divmod(24)
puts "Duration is #{days}d#{hours}h#{minutes}m#{seconds}s"