diff --git a/tv/favicon.ico b/tv/favicon.ico deleted file mode 100644 index 7f4c338..0000000 Binary files a/tv/favicon.ico and /dev/null differ diff --git a/tv/index.html b/tv/index.html deleted file mode 100644 index 8f22f08..0000000 --- a/tv/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - -ytmnd-tv - - - - -
- - - - - - - - - diff --git a/tv/js/audio.js b/tv/js/audio.js deleted file mode 100644 index 5b86ddf..0000000 --- a/tv/js/audio.js +++ /dev/null @@ -1,100 +0,0 @@ -var audio = (function(){ - - var audio = {} - - var context = new AudioContext() - var source - var current = "" - var timeout - - var bufs = {} - var sources = {} - - audio.preload = function(site, loader){ - loader.register(site.domain + "_sound") - var request = new XMLHttpRequest() - request.open('GET', site.sound_url, true) - request.responseType = 'arraybuffer' - request.onload = function() { - context.decodeAudioData(request.response, function(buf) { - bufs[site.domain] = buf - loader.ready(site.domain + "_sound") - }, function () { - ytmnd.error() - }) - } - request.send() - } - - audio.loaded = function(domain){ - return (domain in bufs) - } - - audio.make_source = function(domain){ - var buf = bufs[domain] - var source = context.createBufferSource() - source.connect(context.destination) - source.buffer = buf - - sources[domain] = sources[domain] || [] - sources[domain].push(source) - return source - } - - audio.play = function(domain){ - console.log("play", domain) - - current = domain - - var source - - var startTime = context.currentTime - var delay - - clearTimeout(timeout); - - (function loop(){ - if (source) { - var dt = context.currentTime - startTime - console.log("got a source", dt, delay) - if (dt > 20) { - ytmnd.next() - } - else { - timeout = setTimeout(loop, delay) - source.start(0) - source.started = true - source = audio.make_source(domain) - } - } - else { - timeout = setTimeout(loop, 0) - source = audio.make_source(domain) - delay = source.buffer.duration * 1000 - (source.buffer.duration < 2 ? 0 : 60) - } - })() - - } - - audio.stop_current = function(){ - audio.stop(current) - current = "" - } - - audio.stop = function(domain){ - if (! sources[domain]) return - - clearTimeout(timeout) - - sources[domain].forEach(function(source){ - if (source.started) { - source.stop(0) - } - }) - sources[domain] = [] - delete bufs[domain] - } - - return audio - -})() diff --git a/tv/js/vendor/fetch.js b/tv/js/vendor/fetch.js deleted file mode 100644 index 1b4c275..0000000 --- a/tv/js/vendor/fetch.js +++ /dev/null @@ -1,330 +0,0 @@ -(function() { - 'use strict'; - - if (self.fetch) { - return - } - - function normalizeName(name) { - if (typeof name !== 'string') { - name = name.toString(); - } - if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) { - throw new TypeError('Invalid character in header field name') - } - return name.toLowerCase() - } - - function normalizeValue(value) { - if (typeof value !== 'string') { - value = value.toString(); - } - return value - } - - function Headers(headers) { - this.map = {} - - if (headers instanceof Headers) { - headers.forEach(function(value, name) { - this.append(name, value) - }, this) - - } else if (headers) { - Object.getOwnPropertyNames(headers).forEach(function(name) { - this.append(name, headers[name]) - }, this) - } - } - - Headers.prototype.append = function(name, value) { - name = normalizeName(name) - value = normalizeValue(value) - var list = this.map[name] - if (!list) { - list = [] - this.map[name] = list - } - list.push(value) - } - - Headers.prototype['delete'] = function(name) { - delete this.map[normalizeName(name)] - } - - Headers.prototype.get = function(name) { - var values = this.map[normalizeName(name)] - return values ? values[0] : null - } - - Headers.prototype.getAll = function(name) { - return this.map[normalizeName(name)] || [] - } - - Headers.prototype.has = function(name) { - return this.map.hasOwnProperty(normalizeName(name)) - } - - Headers.prototype.set = function(name, value) { - this.map[normalizeName(name)] = [normalizeValue(value)] - } - - Headers.prototype.forEach = function(callback, thisArg) { - Object.getOwnPropertyNames(this.map).forEach(function(name) { - this.map[name].forEach(function(value) { - callback.call(thisArg, value, name, this) - }, this) - }, this) - } - - function consumed(body) { - if (body.bodyUsed) { - return Promise.reject(new TypeError('Already read')) - } - body.bodyUsed = true - } - - function fileReaderReady(reader) { - return new Promise(function(resolve, reject) { - reader.onload = function() { - resolve(reader.result) - } - reader.onerror = function() { - reject(reader.error) - } - }) - } - - function readBlobAsArrayBuffer(blob) { - var reader = new FileReader() - reader.readAsArrayBuffer(blob) - return fileReaderReady(reader) - } - - function readBlobAsText(blob) { - var reader = new FileReader() - reader.readAsText(blob) - return fileReaderReady(reader) - } - - var support = { - blob: 'FileReader' in self && 'Blob' in self && (function() { - try { - new Blob(); - return true - } catch(e) { - return false - } - })(), - formData: 'FormData' in self - } - - function Body() { - this.bodyUsed = false - - - this._initBody = function(body) { - this._bodyInit = body - if (typeof body === 'string') { - this._bodyText = body - } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { - this._bodyBlob = body - } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { - this._bodyFormData = body - } else if (!body) { - this._bodyText = '' - } else { - throw new Error('unsupported BodyInit type') - } - } - - if (support.blob) { - this.blob = function() { - var rejected = consumed(this) - if (rejected) { - return rejected - } - - if (this._bodyBlob) { - return Promise.resolve(this._bodyBlob) - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as blob') - } else { - return Promise.resolve(new Blob([this._bodyText])) - } - } - - this.arrayBuffer = function() { - return this.blob().then(readBlobAsArrayBuffer) - } - - this.text = function() { - var rejected = consumed(this) - if (rejected) { - return rejected - } - - if (this._bodyBlob) { - return readBlobAsText(this._bodyBlob) - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as text') - } else { - return Promise.resolve(this._bodyText) - } - } - } else { - this.text = function() { - var rejected = consumed(this) - return rejected ? rejected : Promise.resolve(this._bodyText) - } - } - - if (support.formData) { - this.formData = function() { - return this.text().then(decode) - } - } - - this.json = function() { - return this.text().then(JSON.parse) - } - - return this - } - - // HTTP methods whose capitalization should be normalized - var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] - - function normalizeMethod(method) { - var upcased = method.toUpperCase() - return (methods.indexOf(upcased) > -1) ? upcased : method - } - - function Request(url, options) { - options = options || {} - this.url = url - - this.credentials = options.credentials || 'omit' - this.headers = new Headers(options.headers) - this.method = normalizeMethod(options.method || 'GET') - this.mode = options.mode || null - this.referrer = null - - if ((this.method === 'GET' || this.method === 'HEAD') && options.body) { - throw new TypeError('Body not allowed for GET or HEAD requests') - } - this._initBody(options.body) - } - - function decode(body) { - var form = new FormData() - body.trim().split('&').forEach(function(bytes) { - if (bytes) { - var split = bytes.split('=') - var name = split.shift().replace(/\+/g, ' ') - var value = split.join('=').replace(/\+/g, ' ') - form.append(decodeURIComponent(name), decodeURIComponent(value)) - } - }) - return form - } - - function headers(xhr) { - var head = new Headers() - var pairs = xhr.getAllResponseHeaders().trim().split('\n') - pairs.forEach(function(header) { - var split = header.trim().split(':') - var key = split.shift().trim() - var value = split.join(':').trim() - head.append(key, value) - }) - return head - } - - Body.call(Request.prototype) - - function Response(bodyInit, options) { - if (!options) { - options = {} - } - - this._initBody(bodyInit) - this.type = 'default' - this.url = null - this.status = options.status - this.ok = this.status >= 200 && this.status < 300 - this.statusText = options.statusText - this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers) - this.url = options.url || '' - } - - Body.call(Response.prototype) - - self.Headers = Headers; - self.Request = Request; - self.Response = Response; - - self.fetch = function(input, init) { - // TODO: Request constructor should accept input, init - var request - if (Request.prototype.isPrototypeOf(input) && !init) { - request = input - } else { - request = new Request(input, init) - } - - return new Promise(function(resolve, reject) { - var xhr = new XMLHttpRequest() - - function responseURL() { - if ('responseURL' in xhr) { - return xhr.responseURL - } - - // Avoid security warnings on getResponseHeader when not allowed by CORS - if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) { - return xhr.getResponseHeader('X-Request-URL') - } - - return; - } - - xhr.onload = function() { - var status = (xhr.status === 1223) ? 204 : xhr.status - if (status < 100 || status > 599) { - reject(new TypeError('Network request failed')) - return - } - var options = { - status: status, - statusText: xhr.statusText, - headers: headers(xhr), - url: responseURL() - } - var body = 'response' in xhr ? xhr.response : xhr.responseText; - resolve(new Response(body, options)) - } - - xhr.onerror = function() { - reject(new TypeError('Network request failed')) - } - - xhr.open(request.method, request.url, true) - - if (request.credentials === 'include') { - xhr.withCredentials = true - } - - if ('responseType' in xhr && support.blob) { - xhr.responseType = 'blob' - } - - request.headers.forEach(function(value, name) { - xhr.setRequestHeader(name, value) - }) - - xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) - }) - } - self.fetch.polyfill = true -})(); \ No newline at end of file diff --git a/tv/js/vendor/loader.js b/tv/js/vendor/loader.js deleted file mode 100644 index e0a193a..0000000 --- a/tv/js/vendor/loader.js +++ /dev/null @@ -1,86 +0,0 @@ -var Loader = Loader || (function(){ - function Loader (readyCallback, view){ - this.assets = {}; - this.images = []; - this.readyCallback = readyCallback; - this.count = 0 - this.view = view - this.loaded = false - } - - // Register an asset as loading - Loader.prototype.register = function(s){ - this.assets[s] = false; - this.count += 1 - } - - // Signal that an asset has loaded - Loader.prototype.ready = function(s){ - window.debug && console.log("ready >> " + s); - - this.assets[s] = true; - if (this.loaded) return; - - this.view && this.view.update( this.percentRemaining() ) - - if (! this.isReady()) return; - - this.loaded = true; - if (this.view) { - this.view && this.view.finish(this.readyCallback) - } - else { - this.readyCallback && this.readyCallback(); - } - } - - // (boolean) Is the loader ready? - Loader.prototype.isReady = function(){ - for (var s in this.assets) { - if (this.assets.hasOwnProperty(s) && this.assets[s] != true) { - return false; - } - } - return true; - } - - // (float) Percentage of assets remaining - Loader.prototype.percentRemaining = function(){ - return this.remainingAssets() / this.count - } - - // (int) Number of assets remaining - Loader.prototype.remainingAssets = function(){ - var n = 0; - for (var s in this.assets) { - if (this.assets.hasOwnProperty(s) && this.assets[s] != true) { - n++; - // console.log('remaining: ' + s); - } - } - return n; - } - - // Preload the images in config.images - Loader.prototype.preloadImages = function(images){ - this.register("preload"); - for (var i = 0; i < images.length; i++) { - this.preloadImage(images[i]); - } - this.ready("preload"); - } - Loader.prototype.preloadImage = function(src){ - if (! src || src == "none") return; - var _this = this; - this.register(src); - var img = new Image(); - img.onload = function(){ - _this.ready(src); - } - img.src = src; - if (img.complete) img.onload(); - _this.images.push(img); - } - - return Loader; -})(); \ No newline at end of file diff --git a/tv/js/vendor/util.js b/tv/js/vendor/util.js deleted file mode 100644 index 8c9807a..0000000 --- a/tv/js/vendor/util.js +++ /dev/null @@ -1,18 +0,0 @@ -function random(){ return Math.random() } -function rand(n){ return (Math.random()*n) } -function randint(n){ return rand(n)|0 } -function randrange(a,b){ return a + rand(b-a) } -function randsign(){ return random() >= 0.5 ? -1 : 1 } -function choice(a){ return a[randint(a.length)] } - -function toArray(a){ return Array.prototype.slice.call(a) } - -function shuffle(a){ - for (var i = a.length; i > 0; i--){ - var r = randint(i) - var swap = a[i-1] - a[i-1] = a[r] - a[r] = swap - } - return a -} diff --git a/tv/js/ytmnd.js b/tv/js/ytmnd.js deleted file mode 100644 index 3254ef4..0000000 --- a/tv/js/ytmnd.js +++ /dev/null @@ -1,143 +0,0 @@ -var ytmnd = (function(){ - - var ytmnd = {} - var sites = [] - var loaded = {} - var index = 0 - var loading = false - var next_domain = "" - - var base_href = 'https://ltho.s3.amazonaws.com/ytmnd' - - ytmnd.init = function(names){ - var loader = new Loader(ytmnd.ready) - loader.register('init') - names.forEach(function(name){ - loader.register(name) - fetch("users/" + name + '.json').then(function(response){ - return response.json() - }).then(function(json){ - sites = sites.concat(json) - loader.ready(name) - }) - }) - loader.ready('init') - } - - ytmnd.ready = function(){ - shuffle(sites) - ytmnd.bind() - ytmnd.play_index(index) - } - - ytmnd.bind = function(){ - window.addEventListener("keydown", function(e){ - console.log(e.keyCode) - switch (e.keyCode){ - case 37: // left - case 38: // up - ytmnd.prev() - break - case 32: // space - case 39: // right - case 40: // down - ytmnd.next() - break - } - }) - } - - ytmnd.preload = function(site){ - site.image_url = base_href + "/" + site.username + "/" + site.domain + "." + site.image_type - site.sound_url = base_href + "/" + site.username + "/" + site.domain + "." + site.sound_type - - var loader = new Loader (function(){ - loaded[site.domain] = site - if (next_domain == site.domain) { - ytmnd.play(site) - next_domain = "" - loading = false - } - }) - loader.register('init') - loader.preloadImage( site.image_url ) - audio.preload( site, loader ) - loader.ready('init') - } - - ytmnd.preload_index = function(index){ - var site = sites[index] - ytmnd.preload(site) - } - - ytmnd.play_index = function(index){ - var site = sites[index] - if (loaded[site.domain]) { - ytmnd.play(site) - } - else { - next_domain = site.domain - ytmnd.preload(site) - loading = true - } - } - - ytmnd.play = function(site){ - document.querySelector("title").innerHTML = site.title - document.body.style.backgroundColor = "#" + site.bgcolor - document.body.style.backgroundImage = "url(" + site.image_url + ")" - document.body.className = site.placement - audio.play(site.domain) - zoomtext.render(site) - } - - ytmnd.stop = function(){ - var site = sites[index] - loaded[site.domain] = false - audio.stop(site.domain) - zoomtext.empty() - } - - ytmnd.prev = function(){ - ytmnd.stop() - index = (index-1) % sites.length - ytmnd.play_index(index) - setTimeout(function(){ - ytmnd.preload_index((index-1 + sites.length) % sites.length) - }, 1000) - } - - ytmnd.next = function(){ - ytmnd.stop() - index = (index+1) % sites.length - ytmnd.play_index(index) - setTimeout(function(){ - ytmnd.preload_index((index+1) % sites.length) - }, 1000) - } - - ytmnd.error = function(){ - ytmnd.next() - } - - return ytmnd -})() - - -/* - simplified_info = { -// 'domain': domain, -// 'title': title, -// 'username': username, - 'work_safe': work_safe, -// 'bgcolor': bgcolor, -// 'placement': placement, -// 'zoom_text': zoom_text, - 'image': domain + "." + gif_type, - 'image_type': gif_type, - 'image_origin': image_origin, -// 'sound': domain + "." + wav_type, -// 'sound_type': wav_type, -// 'sound_origin': sound_origin, - } -*/ \ No newline at end of file diff --git a/tv/js/zoomtext.js b/tv/js/zoomtext.js deleted file mode 100644 index 235953a..0000000 --- a/tv/js/zoomtext.js +++ /dev/null @@ -1,56 +0,0 @@ -var zoomtext = (function(){ - - var zoomtext = {} - - var el = document.querySelector("#zoom_text") - - zoomtext.empty = function(){ - el.innerHTML = "" - } - - zoomtext.render = function(site){ - if (! site.zoom_text.line_1) { - return zoomtext.empty() - } - - var text = site['zoom_text'] - - var offset = 100, rows = "" - if ("line_3" in zoom_text && text["line_3"].length > 0) { - rows += zoomtext.add_row( text['line_3'], offset, 500 ) - offset += 50 - } - if ("line_2" in zoom_text && text["line_2"].length > 0) { - rows += zoomtext.add_row( text['line_2'], offset, 250 ) - offset += 50 - } - if ("line_1" in zoom_text && text["line_1"].length > 0) { - rows += zoomtext.add_row( text['line_1'], offset, 500 ) - } - - el.innerHTML = rows.join("") - } - zoomtext.add_row = function(text, offset, top){ - var z_index, row_left, row_top, font_size, color - var row = "" - for (var i = 1; i < 51; i++) { - z_index = offset + i - row_left = i * 2 - row_top = top + i - font_size = i * 2 - if (i == 50) { - color = 0 - } - else { - color = i * 4 - } - - row += "
" + text + "
" - } - return row - } - - return zoomtext -})() \ No newline at end of file