require 'forwardable' module RtmpMeta class Parser PATTERN = /duration\s+(?\d+\.?\d+)$/ attr_reader :raw_data def initialize raw_data @raw_data = raw_data end def duration @duration ||= metadata[:duration] end protected def metadata @metadata ||= parse_raw_data end def parse_raw_data match = PATTERN.match(raw_data) { duration: match ? match[:duration] : '0' } end end end module RtmpMeta class MetadataCommand attr_reader :rtmp_url def initialize rtmp_url @rtmp_url = rtmp_url end def execute fetch_metadata.encode('UTF-8', invalid: :replace, replace: '?') end protected def fetch_metadata `rtmpdump -r '#{rtmp_url}' -o '/dev/null' --stop '0.01' 2>&1` end end end module RtmpMeta class Stream extend Forwardable attr_reader :metadata def_delegator :metadata, :duration def initialize stream, path url = [stream, path].join('/') @raw_data = MetadataCommand.new(url).execute @metadata = Parser.new(@raw_data) end end end