// vim: et:ts=4:sw=4:sts=4:ft=javascript /*@ Ox.VideoElement VideoElement Object () -> VideoElement Object (options) -> VideoElement Object (options, self) -> VideoElement Object options Options object self shared private variable @*/ Ox.VideoElement = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ autoplay: false, preload: 'none', src: [] }) .options(options || {}) .css({width: '100%', height: '100%'}); Ox.Log('Video', 'VIDEO ELEMENT OPTIONS', self.options) self.items = []; self.paused = true; self.$video = $('
'); if (Ox.isFunction(self.options.src)) { self.isPlaylist = true; self.currentItem = 0; self.currentPage = 0; self.loadedMetadata = false; self.pageLength = 2; self.options.src(function(items) { self.numberOfItems = items; self.numberOfPages = Math.ceil(self.numberOfItems / self.pageLength); loadPages(function() { Ox.Log('Video', 'VIDEO PAGES LOADED'); setCurrentItem(0); if (!self.loadedMedatata) { self.loadedMetadata = true; that.triggerEvent('loadedmetadata'); that.triggerEvent('pointschange'); // fixme: needs to be triggered again, loadedmetadata messes with duration } }); }); } else { self.numberOfItems = 1; self.items.push(loadItem(self.options.src)); } function getCurrentPage() { return Math.floor(self.currentItem / self.pageLength); } function getCurrentTime() { return self.items[self.currentItem].offsets[self.currentPart] + self.video.currentTime; } function getset(key, value) { var ret; if (Ox.isUndefined(value)) { ret = self.video[key] } else { self.video[key] = value; ret = that; } return ret; } function loadPage(page, callback) { Ox.Log('Video', 'VIDEO loadPage', page) //page = Ox.mod(page, self.numberOfPages); var loadedmetadata = 0, start = page * self.pageLength, stop = Math.min(start + self.pageLength, self.numberOfItems), pageLength = stop - start; if (!self.items[start]) { self.options.src([start, stop], function(data) { data.forEach(function(data, i) { self.items[start + i] = loadItem(data.parts, data.points, function(item) { if (++loadedmetadata == pageLength) { Ox.Log('Video', 'VIDEO page', page, 'loaded') callback && callback(); } }); }); }); } else { Ox.Log('Video', 'PAGE IN CACHE') callback && callback(); } } function loadPages(callback) { var currentPage = self.currentPage, nextPage = Ox.mod(currentPage + 1, self.numberOfPages), previousPage = Ox.mod(currentPage - 1, self.numberOfPages); loadPage(currentPage, function() { if (nextPage != currentPage) { loadPage(nextPage, function() { if (previousPage != currentPage && previousPage != nextPage) { unloadPage(previousPage); } }); } callback && callback(); }); } function loadItem(src, points, callback) { src = Ox.isArray(src) ? src : [src]; var item = { currentPart: 0, duration: 0, durations: src.map(function() { return 0; }), offsets: [], parts: src.length }; if (points) { item.points = points; } item.$videos = src.map(function(src, i) { // in all browsers except firefox, // loadedmetadata fires only once per src src += '?' + Ox.uid(); return $('