title: How To Obtain YouTube Video Download Url Just Like KeepVid (2017)?
body: <p>I'm writing a youtube video downloader. Let's use this video as an example:</p>
  
  <p><a href="https://www.youtube.com/watch?v=_UbDeqPdUek" rel="noreferrer">https://www.youtube.com/watch?v=_UbDeqPdUek</a></p>
  
  <p>When researching how to grab a YouTube video's url, I came across a snippet of code right here on stackoverflow:</p>
  
  <pre><code>(function() {
      return ytplayer.config.args.adaptive_fmts
          .split(',')
          .map(item =&gt; item
              .split('&amp;')
              .reduce((prev, curr) =&gt; (curr = curr.split('='),
                  Object.assign(prev, { [curr[0]]: decodeURIComponent(curr[1]) })
              ), {})
          )
          .reduce((prev, curr) =&gt; Object.assign(prev, {
              [curr.quality_label || curr.type]: curr
          }), {});
  })();
  </code></pre>
  
  <p>Execute this in the chrome dev console on the youtube url above, and you'll see that it will spew forth an object with information, including video urls.</p>
  
  <p>The 'url' property within the '720p' property, is the following:</p>
  
  <pre><code>https://r2---sn-5hne6nlk.googlevideo.com/videoplayback?mn=sn-5hne6nlk&amp;ip=92.111.133.132&amp;mm=31&amp;sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cexpire&amp;itag=247&amp;mime=video%2Fwebm&amp;dur=250.800&amp;id=o-AEgCrHyMCCJXgH39WmxsSwNs01bFa3BDVFEIzgAyrthL&amp;mv=m&amp;pl=18&amp;mt=1500667926&amp;requiressl=yes&amp;ms=au&amp;expire=1500689653&amp;initcwndbps=1997500&amp;keepalive=yes&amp;key=yt6&amp;ei=lWByWcWwI4Th1gKa2aDoCg&amp;signature=596BF2603202A1BC60493C8263928FB365A14B2A.92D082149A543786BA5C29A547A8F78DE9346F95&amp;source=youtube&amp;clen=47937010&amp;gir=yes&amp;ipbits=0&amp;lmt=1449652247373936
  </code></pre>
  
  <p>When I paste this url into a chrome tab, it starts playing the video in a barebones window. You can use this link to download the video. The problem is, the video has no sound!</p>
  
  <p>When I use <a href="http://keepvid.com/?url=https://www.youtube.com/watch?v=_UbDeqPdUek&amp;from=plugin#downloader" rel="noreferrer">keepvid</a> to download the video, it will have the following url on the 720p download button:</p>
  
  <pre><code>https://r17---sn-o097znll.googlevideo.com/videoplayback?lmt=1470986968011625&amp;mt=1500670510&amp;dur=250.891&amp;itag=22&amp;ipbits=0&amp;ms=au&amp;sparams=dur%2Cei%2Cid%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire&amp;ei=pWpyWZ75BZyf1gLf6rXQCA&amp;id=o-AMPIR2-sd--NM8eDZyPKMqOu1B5qqSkBd1brw-H44ARx&amp;pl=24&amp;mn=sn-o097znll&amp;mm=31&amp;source=youtube&amp;signature=6F5B6D2EFCF5CD600D9B12C984A19DBA58AC6A7E.CC2EE5E63809D4C9A07BB2C194328C7825015976&amp;ratebypass=yes&amp;mv=m&amp;mime=video%2Fmp4&amp;ip=159.253.144.86&amp;requiressl=yes&amp;key=yt6&amp;expire=1500692229&amp;title=Cubs+Meet+Adult+Tiger+For+The+First+Time+-+Tigers+About+The+House+-+BBC
  </code></pre>
  
  <p>The differences between both urls (and the query params) are small. But the fact is that keepvid's url works better than mine:</p>
  
  <ol>
  <li>It spews up the file as a download, rather than playing it in the browser.</li>
  <li>It has sound.</li>
  </ol>
  
  <p>For all of your convenience, here are the url-decoded, formatted versions of these urls, with the parameters alphabetically ordered.</p>
  
  <p>My url which I got from the js snippet above, with sound not working:</p>
  
  <pre><code>https://r2---sn-5hne6nlk.googlevideo.com/videoplayback
  clen=47937010
  dur=250.800
  ei=lWByWcWwI4Th1gKa2aDoCg
  expire=1500689653
  gir=yes
  id=o-AEgCrHyMCCJXgH39WmxsSwNs01bFa3BDVFEIzgAyrthL
  initcwndbps=1997500
  ip=92.111.133.132
  ipbits=0
  itag=247
  keepalive=yes
  key=yt6
  lmt=1449652247373936
  mime=video/webm
  mm=31
  mn=sn-5hne6nlk
  ms=au
  mt=1500667926
  mv=m
  pl=18
  requiressl=yes
  signature=596BF2603202A1BC60493C8263928FB365A14B2A.92D082149A543786BA5C29A547A8F78DE9346F95
  source=youtube
  sparams=clen,dur,ei,gir,id,initcwndbps,ip,ipbits,itag,keepalive,lmt,mime,mm,mn,ms,mv,pl,requiressl,source,expire
  </code></pre>
  
  <p>The url which I got from keepvid, with sound working:</p>
  
  <pre><code>https://r17---sn-o097znll.googlevideo.com/videoplayback
  dur=250.891
  ei=pWpyWZ75BZyf1gLf6rXQCA
  expire=1500692229
  id=o-AMPIR2-sd--NM8eDZyPKMqOu1B5qqSkBd1brw-H44ARx
  ip=159.253.144.86
  ipbits=0
  itag=22
  key=yt6
  lmt=1470986968011625
  mime=video/mp4
  mm=31
  mn=sn-o097znll
  ms=au
  mt=1500670510
  mv=m
  pl=24
  ratebypass=yes
  requiressl=yes
  signature=6F5B6D2EFCF5CD600D9B12C984A19DBA58AC6A7E.CC2EE5E63809D4C9A07BB2C194328C7825015976
  source=youtube
  sparams=dur,ei,id,ip,ipbits,itag,lmt,mime,mm,mn,ms,mv,pl,ratebypass,requiressl,source,expire
  title=Cubs Meet Adult Tiger For The First Time - Tigers About The House - BBC
  </code></pre>
  
  <p>As you can see, the urls/parameters are very similar. But how does keepvid manage to produce a file url that has the sound working, while my js snippet craps out on me without audio?</p>
  
  <p>The urls have a signature as a parameter. This is likely the signature for (some of the) query parameters itself. Changing something small in a parameter (delete it, or change its value), results in the url getting access denied. This makes it hard to experiment with it.</p>
  
  <p>The js snippet simply accesses an online variable and digs the video info from it. But what's the snippet missing that's causing its urls to refer to soundless videos?</p>
  
  <p>Can anybody help me to programmatically obtain a url just like keepvid's, which will result in a downloaded file with working audio?</p>
  
  <p><strong>[Update]</strong></p>
  
  <p>I've just learned you can grab video info like such:</p>
  
  <pre><code>http://youtube.com/get_video_info?video_id=_UbDeqPdUek
  </code></pre>
  
  <p>It yields a big file with loads of info, that I haven't figured out how to parse yet.</p>
  
  <p>I must be on the right path, because this is how <a href="https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/youtube.py#L1455" rel="noreferrer">youtube-dl</a> is doing it. And that program works flawlessly.</p>
  
  <p>I suppose I could simply reverse engineer youtube-dl (costs time). Or even call it from my C# program using Process (makes me dependent on it).</p>
  
  <p>But that still leaves me with the question of how a person would figure this out on their own, if no help was available?</p>