Skip to content

Instantly share code, notes, and snippets.

View MeoMix's full-sized avatar

Sean Anderson MeoMix

  • San Francisco, CA
View GitHub Profile
// Notify background of video information data necessary to render the video on another page.
// The type of video (including codec) as well as the ArrayBuffer of video data.
var message = {
buffer: this.response.slice(0),
bufferType: videoInfo.type
};
// Be sure to mark the buffer as transferable as it can be a large amount of data.
window.top.postMessage(message, origin, [message.buffer]);
_onWindowMessage: function(message) {
// When receiving a message of buffer data from YouTube's API, store it.
if (message.data && message.data.buffer) {
this.get('buffers').push(message.data.buffer);
this.set('bufferType', message.data.bufferType);
}
},
<html>
<head>
<title>Foreground</title>
<link rel="stylesheet" href="foreground.css">
</head>
<body>
<div class="video-container">
<video id='video'></video>
</div>
var MediaSourceWrapper = require('foreground/model/mediaSourceWrapper');
var VideoView = Marionette.ItemView.extend({
el: '#video',
mediaSourceWrapper: null,
mediaSourceWrapperEvents: {
'change:objectURL': '_onMediaSourceWrapperChangeObjectURL'
},
var SourceBufferWrapper = require('foreground/model/sourceBufferWrapper');
var MediaSourceWrapper = Backbone.Model.extend({
defaults: function() {
return {
mediaSource: new window.MediaSource(),
sourceBufferWrapper: null,
// The video encoding format and codec used to render mediaSource; i.e. video/webm codecs="vp9"
bufferType: '',
// The URL which points to mediaSource's data
var SourceBufferWrapper = Backbone.Model.extend({
defaults: function() {
return {
sourceBuffer: null,
appendedBufferCount: 0,
// Buffered data which has already been leveraged by YouTube is cached on the background page and re-used as needed.
bufferCache: []
};
},
// Create the port needed to communicate with the parent extension.
this.initializePort = function() {
this.port = chrome.runtime.connect({
name: 'youTubeIFrameConnectRequest'
});
// The extension can request the *exact* time of YouTube's video player.
// Respond with that value, but also include a timestamp to account for the time it takes to send the postMessage.
this.port.onMessage.addListener(function(message) {
if (message === 'getCurrentTimeHighPrecision') {
// Send a message to YouTube's iframe to figure out what the current time is of the video element inside of the iframe.
requestCurrentTimeHighPrecision: function() {
var iframePort = this.get('iframePort');
iframePort.postMessage('getCurrentTimeHighPrecision');
}
_onYouTubeIFrameMessage: function(message) {
if (!_.isUndefined(message.currentTimeHighPrecision)) {
this.trigger('receive:currentTimeHighPrecision', this, message);
}
_setCurrentTime: function(playerState, currentTimeHighPrecision, timestamp) {
// If the player is playing then currentTimeHighPrecision will be slightly out-of-sync due to the time it takes to request
// the information. So, subtract an offset of the time it took to receive the message.
if (playerState === PlayerState.Playing) {
var offset = performance.now() - timestamp;
currentTimeHighPrecision -= offset * .001;
}
this.el.currentTime = currentTimeHighPrecision;
}
define(function(require) {
'use strict';
require('backbone.marionette');
Marionette.Region.buildRegion = function(regionConfig, DefaultRegionClass) {
if (_.isString(regionConfig)) {
regionConfig = '[data-region=' + regionConfig + ']';
return this._buildRegionFromSelector(regionConfig, DefaultRegionClass);
}