- return t_parameter
- end
-
-
- def get_available_formats(page_data)
- # Parse the list of available formats from the "fmt_list" Flash
- # variable.
- available_formats = []
- fmt_list_regex = /\"fmt_list\"\:[[:space:]]\"([^\"]+?)\"/
- matches = fmt_list_regex.match(page_data)
-
- if matches.nil?
- return nil
- else
- fmts_string = CGI::unescape(matches[1])
-
- fmts_string.split(',').each do |fmt|
- # Each "fmt" will look something like,
- #
- # 35/640000/9/0/115
- #
- # with the format identifier coming before the first slash.
- first_slash_idx = fmt.index('/')
- available_formats << fmt[0...first_slash_idx].to_i
- end
-
+ 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