+ def get_format_url_map(page_data)
+ # Youtube has implemented a new fmt_url_map that (perhaps
+ # unsurprisingly) maps formats to video URLs. This makes it
+ # easyish to parse the video URLs.
+ url_map = {}
+ url_map_regex = /fmt_url_map=([^&\"]+)/
+
+ matches = url_map_regex.match(page_data)
+
+ if (matches.nil? || matches.length < 1)
+ raise StandardError.new("Could not parse the fmt_url_map Flash variable.")
+ end
+
+ # The map is stored entirely in one Flash variable. The format is
+ # key|value,key|value,...
+ maptext = CGI::unescape(matches[1])
+ entries = maptext.split(',')
+ entries.each do |entry|
+ key = entry.split('|')[0].to_i
+ value = entry.split('|')[1]
+ url_map[key] = value
+ end
+
+ if (url_map.length < 1)
+ raise StandardError.new("Could not find any valid format URLs.")
+ end
+
+ return url_map
+ end
+
+
+ def get_desired_format(available_formats)
+ # Check for the presence of formats, in order of preference
+ # (quality). That is, we check for the best formats first. As soon
+ # as a format is found to be available, we return it as the
+ # desired format, since the first format we find is going to be
+ # the best available format.
+ return 37 if available_formats.include?(37)
+ return 22 if available_formats.include?(22)
+ return 35 if available_formats.include?(35)
+ return 18 if available_formats.include?(18)
+ return 34 if available_formats.include?(34)
+ return 17 if available_formats.include?(17)
+
+ # Available formats can't be empty (we would have raised an error
+ # in get_available_formats), so if there's some unknown format
+ # here we might as well return it as a last resort.
+ return available_formats[0]