Created
July 21, 2015 01:32
-
-
Save MeoMix/c417013ce502cf8f797b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
objectURL: null | |
}; | |
}, | |
initialize: function() { | |
// IMPORTANT: Prefer binding like this rather than using .bind(this) inline because bind will return a new function. | |
// This will break unobserve because it expects to be given a reference to the original function. | |
this._onSourceOpen = this._onSourceOpen.bind(this); | |
this._onSourceClose = this._onSourceClose.bind(this); | |
this._onSourceEnded = this._onSourceEnded.bind(this); | |
var mediaSource = this.get('mediaSource'); | |
mediaSource.addEventListener('sourceopen', this._onSourceOpen); | |
mediaSource.addEventListener('sourceclose', this._onSourceClose); | |
mediaSource.addEventListener('sourceended', this._onSourceEnded); | |
this.on('change:bufferType', this._onChangeBufferType); | |
}, | |
cleanup: function() { | |
var mediaSource = this.get('mediaSource'); | |
mediaSource.removeEventListener('sourceopen', this._onSourceOpen); | |
mediaSource.removeEventListener('sourceclose', this._onSourceClose); | |
mediaSource.removeEventListener('sourceended', this._onSourceEnded); | |
this._detachBuffer(); | |
}, | |
_onChangeBufferType: function(model, bufferType) { | |
this._setBuffer(bufferType); | |
}, | |
_onSourceOpen: function() { | |
this._attachBuffer(); | |
}, | |
_onSourceClose: function() { | |
this._detachBuffer(); | |
}, | |
_onSourceEnded: function() { | |
this._detachBuffer(); | |
}, | |
// If a bufferType is known then create a sourceBuffer which will expect content encoded with that bufferType. | |
// Otherwise, clean-up any existing buffer since no content is expected. | |
_setBuffer: function(bufferType) { | |
if (bufferType === '') { | |
this._destroyBuffer(); | |
} else { | |
this._createBuffer(); | |
} | |
}, | |
// Creating a buffer mostly consists of setting the objectURL of the source. | |
// Once that is set, the source will transition to the 'open' state and the buffer will become usable. | |
_createBuffer: function() { | |
if (this.get('sourceBufferWrapper') === null) { | |
this.set({ | |
sourceBufferWrapper: new SourceBufferWrapper({ | |
bufferCache: chrome.extension.getBackgroundPage().player.get('buffers') | |
}), | |
// Recreate objectURL whenever sourceBufferWrapper is modified or video won't start properly. | |
objectURL: window.URL.createObjectURL(this.get('mediaSource')) | |
}); | |
} else { | |
console.error('sourceBufferWrapper already created'); | |
} | |
}, | |
// Destroying a buffer means cleaning up the existing buffer from the source and clearing the objectURL. | |
// When the objectURL is cleared the source will transition to the 'closed' state and become unusable. | |
_destroyBuffer: function() { | |
var sourceBufferWrapper = this.get('sourceBufferWrapper'); | |
if (sourceBufferWrapper !== null) { | |
this.get('mediaSource').removeSourceBuffer(sourceBufferWrapper.get('sourceBuffer')); | |
// Setting objectURL to null will cause _onSourceClose to fire because the video element's src is cleared. | |
this.set('objectURL', null); | |
} else { | |
console.error('sourceBuffer already destroyed'); | |
} | |
}, | |
// Only attach a buffer to a MediaSource which is 'open' | |
_attachBuffer: function() { | |
var buffer = this.get('mediaSource').addSourceBuffer(this.get('bufferType')); | |
this.get('sourceBufferWrapper').set('sourceBuffer', buffer); | |
}, | |
// Only detach a buffer from a MediaSource which is 'closed' or 'ended'. | |
_detachBuffer: function() { | |
var sourceBufferWrapper = this.get('sourceBufferWrapper'); | |
if (sourceBufferWrapper !== null) { | |
sourceBufferWrapper.cleanup(); | |
this.set('sourceBufferWrapper', null); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment