]> gitweb.michael.orlitzky.com - dead/whatever-dl.git/commitdiff
Add a fix for Youtube's itag parameter.
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 14 Oct 2011 20:10:24 +0000 (16:10 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 14 Oct 2011 20:10:24 +0000 (16:10 -0400)
Make the fmt_stream_url selection smarter.

src/websites/youtube.rb

index c51ba9264e1ac056845e3c8c3d67dafe44bc1dd3..f9fd05a764f0eef64e4221d24dae7b3e2ea6026f 100644 (file)
@@ -66,20 +66,16 @@ class Youtube < Website
       # We assume that all available formats will have an entry in the
       # fmt_url_map hash.
       video_url = fmt_url_map[desired_format]
-
       return video_url
     rescue StandardError => e
       # If at first you do not succeed, maybe someone decided to
       # change some shit. This alternate method parses
       # url_encoded_fmt_stream_map.
       fmt_streams = get_fmt_stream_list(page_data)
-      video_url = self.unicode_unescape(fmt_streams[0])
-      video_url = CGI::unescape(video_url)
+      video_url = self.choose_best_fmt_stream_url(fmt_streams)
 
-      # Strip off everything after the first space in the URL.
-      # I don't know why this works, but if we leave the space
-      # in (encoded, even), Youtube throws us 403 errors.
-      video_url.gsub!(/ .+$/, '')
+      # The "itag" parameter makes the 403 happen.
+      video_url.gsub!(/itag=\d+&/, '')
     end
 
     return video_url
@@ -106,12 +102,30 @@ class Youtube < Website
 
   protected;
 
+  def choose_best_fmt_stream_url(fmt_stream_urls)
+    # Take a list, generated by get_fmt_stream_list(), and choose the
+    # best URL out of the bunch based on the video format.
+    fmt_stream_urls.each do |fs|
+      if fs =~ /video\/mp4/ and fs =~ /quality=large/
+        return fs
+      elsif fs =~ /quality=large/
+        return fs
+      elsif fs =~ /video\/mp4/
+        return fs
+      else
+        return fs
+      end
+    end
+  end
+
+
   def unicode_unescape(string)
     # Unescape sequences like '\u0026'.
     # Ok, only '\u0026' for now.
     return string.gsub('\u0026', '&')
   end
 
+
   def get_fmt_stream_list(page_data)
     # This is another (new?) method of embedding the video URLs.
     # The url_encoded_fmt_stream_map variable contains a list of URLs
@@ -130,6 +144,16 @@ class Youtube < Website
     urlstring = matches[1]
     urlstring.gsub!('url=', '')
     urls = urlstring.split(',')
+
+    urls.each_index do |idx|
+      urls[idx] = self.unicode_unescape(urls[idx])
+      urls[idx] = CGI::unescape(urls[idx])
+      # Strip off everything after the first space in the URL.
+      # I don't know why this works, but if we leave the space
+      # in (encoded, even), Youtube throws us 403 errors.
+      urls[idx].gsub!(/ .+$/, '')
+    end
+
     return urls
   end