// Run from the dev tools console of any Youtube video
// Accurate as of October 28, 2016. Uses quality + video type for naming now,
// prevents video urls being overwritten.

// ES6 version
const videoUrls = ytplayer.config.args.url_encoded_fmt_stream_map
  .split(',')
  .map(item => item
    .split('&')
    .reduce((prev, curr) => (curr = curr.split('='),
      Object.assign(prev, {[curr[0]]: decodeURIComponent(curr[1])})
    ), {})
  )
  .reduce((prev, curr) => Object.assign(prev, {
    [curr.quality + ':' + curr.type.split(';')[0]]: curr
  }), {});

console.log(videoUrls);

// ES5 version
var videoUrls = ytplayer.config.args.url_encoded_fmt_stream_map
  .split(',')
  .map(function (item) {
    return item
      .split('&')
      .reduce(function (prev, curr) {
        curr = curr.split('=');
        return Object.assign(prev, {[curr[0]]: decodeURIComponent(curr[1])})
      }, {});
  })
  .reduce(function (prev, curr) {
    return Object.assign(prev, {
      [curr.quality + ':' + curr.type.split(';')[0]]: curr
    });
  }, {});

console.log(videoUrls);

// Prior June 2016 buggy version
// var videoUrls = {};
// ytplayer.config.args.url_encoded_fmt_stream_map.split(',').forEach(function (item) {
//   var obj = {};
// 
//   item.split('&').forEach(function (param) {
//     param = param.split('=');
//     obj[param[0]] = decodeURIComponent(param[1]);
//   });
// 
//   videoUrls[obj.quality] = obj;
// });
// 
// console.log(videoUrls);