Skip to content

Instantly share code, notes, and snippets.

View MeoMix's full-sized avatar

Sean Anderson MeoMix

  • San Francisco, CA
View GitHub Profile
// Enables progressive rendering of children by keeping track of indices which are currently rendered.
minRenderedIndex: 0,
maxRenderedIndex: 25,
addItemView: function(item, ItemView, index) {
if (index >= this.minRenderedIndex || index < this.maxRenderedIndex) {
Backbone.Marionette.CompositeView.prototype.addItemView.apply(this, arguments);
}
},
(function () {
var g, h = this;
function l(a) {
a = a.split(".");
for (var b = h, c; c = a.shift();)
if (null != b[c]) b = b[c];
else return null;
return b
}
custom: function () {
var songIds = [
"A9j9AksVWJw",
"LGFmC-ufpk0",
"zOcBmvEwjq8",
"Q_kSnp0fGyQ",
"WLsq8zPvloY",
"def08tcW1x0",
"rSFsYvvSXqc",
"v_Jdf9AWQ-k",
// RUN THIS CODE ON groovebackup.com's console, see screencast for more info.
var playlistTitleAndEntryList = [];
function recursiveParseLinks(links, callback){
if(links.length > 0){
var link = links.shift();
if(link.href.indexOf('exportPlaylist') !== -1){
var xmlHttpRequest = new XMLHttpRequest();
{
"content_scripts": [
{
"matches": [ "*://*.youtube.com/embed/*?enablejsapi=1&origin=chrome-extension:*" ],
"all_frames": true,
"run_at": "document_start",
"js": [ "js/inject/youTubeIFrameInject.js" ]
}
],
"permissions": [
{
"content_scripts": [
{
"matches": [ "*://*.youtube.com/embed/*?enablejsapi=1&origin=chrome-extension:*" ],
"all_frames": true,
"run_at": "document_start",
"js": [ "js/inject/youTubeIFrameInject.js" ]
}
],
"web_accessible_resources": [
// Append a script to the page which will intercept YouTube's server requests and post messages out of the iframe with details about those requests.
// Needs to be an injected script because content scripts are sandboxed in such a way that they do not share variables with appended scripts.
this.injectInterceptorScript = function() {
var interceptorScript = document.createElement('script');
interceptorScript.src = chrome.runtime.getURL('js/inject/interceptor.js');
document.head.appendChild(interceptorScript);
}.bind(this);
var decodedResponse = decodeURIComponent(this.response);
// The 'adaptive-fmts' parameter stores the video information needed.
var encodedAdaptiveFormats = (decodedResponse.split('adaptive_fmts=')[1] || '').replace(/\+/g, ' ');
var encodedAdaptiveFormatList = encodedAdaptiveFormats.split(',');
// Convert the encoded URL of adaptive formats into an array of objects since that's a lot easier to work with.
var decodedAdaptiveFormatList = encodedAdaptiveFormatList.map(function(encodedAdaptiveFormat) {
var decodedAdaptiveFormat = {};
encodedAdaptiveFormat.split('&').forEach(function(parameterPair) {
this.addEventListener('load', function() {
} else if (responseType === 'arraybuffer') {
// The itag is a unique identifier which provides a 1:1 between videoInfo and a video data response.
var itag = (responseURL.split('itag=')[1] || '').split('&')[0];
// There's no guarantee that the current request is a video data response.
if (itag !== '') {
var videoInfo = videoInfoList.filter(function(object) {
return object.itag === itag;
})[0];