class Grabber
Attributes
urls[R]
Public Class Methods
new(manifest, bootstrap, io=nil)
click to toggle source
# File lib/glued/grabber.rb, line 6 def initialize(manifest, bootstrap, io=nil) raise "Only one segment can be handled" if bootstrap.segments != 1 #As we've hardcoded 1 below raise "Not enough fragments" if bootstrap.fragments < 1 raise "Too many fragments" if bootstrap.fragments > 10000 #not sure what this limit should be @uri = "#{manifest.media_filename}.flv" @url = "#{manifest.base_ref}/#{manifest.media_filename}Seg1-Frag" @total_fragments = bootstrap.fragments @urls = [] @downloaded_fragments = [] @fragments_downloaded = 0 #TODO: Track how much has already been downloaded and append from that point raise "Aborting as the download target file '#{@uri}' already exists" if File.exist? @uri @out = io ||= File.new(@uri, 'ab') @out.write(flv_header(1,1)) build end
Private Instance Methods
build()
click to toggle source
# File lib/glued/grabber.rb, line 40 def build #TODO, correctly set the fragment start fragment = 1 while fragment <= @total_fragments @urls << "#{@url}#{fragment}" fragment += 1 end @urls.each { |url| download url } end
download(url)
click to toggle source
# File lib/glued/grabber.rb, line 51 def download url file_name = url.split('/').pop dl = fetch_and_report(url) raise "Invalid content type '#{dl.content_type}' for fragment #{file_name}." unless dl.content_type == 'video/f4f' reader = F4VIO.new(dl.body) f4f = F4F.new(reader) raise "Fragment did not verify" unless f4f.ok? f4f.boxes.each do |box| if box.type == 'mdat' reader.pos = box.content_start @out.write(reader.read(box.content_size)) end end @fragments_downloaded += 1 end
fetch_and_report(url)
click to toggle source
# File lib/glued/grabber.rb, line 73 def fetch_and_report(url) start_time = Time.now dl = Curl::Easy.perform(url) report(dl.body.length, Time.now-start_time) dl end
flv_header(audio, video)
click to toggle source
TODO: Inspect first fragment, test for audio and video, write header accordingly
# File lib/glued/grabber.rb, line 30 def flv_header(audio, video) #Audio and video need to be a 1 or 0 flv_header = ["464c5601050000000900000000"].pack("H*") result = audio << 2 | video flv_header[4] = [result].pack('C') flv_header end
report(number_of_bytes, in_seconds)
click to toggle source
# File lib/glued/grabber.rb, line 83 def report(number_of_bytes, in_seconds) bps = (number_of_bytes*8) / in_seconds kbps = bps/1000 mbps = bps/1000000 print "\rDownloading #{@fragments_downloaded+1}/#{@total_fragments} at #{mbps.round(2)} Mbps" end