class MPD {
/**
*
* @param {object} config - configuration object for the manifest
*/
constructor (config = {
mediaUrl: '',
startNumber: 1,
startTime: 0,
timeOffset: 0,
periodId: 1,
minimumUpdatePeriod: 'PT60S',
type: 'dynamic',
profiles: 'urn:mpeg:dash:profile:isoff-live:2011',
minBufferTime: 'PT12S',
mimetype: 'video/webm'
}) {
this.doc = document.implementation.createDocument(null, 'mpd')
this.mpd = null
this.config = config
this.serializer = new XMLSerializer()
}
/**
*
* @param {Buffer} videoData - initial video data for the stream, must be less than 100kb
*/
*createMpd (videoData) {
while (true) {
this.mpd = this.doc.createElement('MPD')
const date = new Date(Date.now()).toISOString()
this.mpd.setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
this.mpd.setAttribute('xmlns', 'urn:mpeg:dash:schema:mpd:2011')
this.mpd.setAttribute('xsi:schemaLocation', 'urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd')
this.mpd.setAttribute('type', this.config.type)
this.mpd.setAttribute('profiles', this.config.profiles)
this.mpd.setAttribute('minimumUpdatePeriod', this.config.minimumUpdatePeriod)
this.mpd.setAttribute('minBufferTime', this.config.minBufferTime)
this.mpd.setAttribute('availabilityStartTime', date)
// create generators
const periodGenerator = this.createPeriod(this.config.startNumber)
const adaptationSetGenerator = this.createAdaptationSet(this.config.mimetype)
const contentComponentGenerator = this.createContentComponent('video', this.config.startNumber)
const segmentTemplateGenerator = this.createSegmentTemplate(videoData, "1000", "2000", 1, this.config.mediaUrl)
// generate elements
const period = periodGenerator.next().value
const adaptationSet = adaptationSetGenerator.next().value
const contentComponent = contentComponentGenerator.next().value
const segmentTemplate = segmentTemplateGenerator.next().value
// append elements
adaptationSet.appendChild(contentComponent)
adaptationSet.appendChild(segmentTemplate)
period.appendChild(adaptationSet)
this.mpd.appendChild(period)
this.config.startNumber++
yield this.mpd
}
}
/**
*
* @param {integer} id - the id of the period
*/
*createPeriod(id) {
const period = this.doc.createElement('Period')
while (true) {
period.setAttribute('start', `PT${this.config.startTime + this.config.timeOffset}S`)
period.setAttribute('id', id);
console.log('ID:::', id)
yield period;
}
}
/**
*
* @param {string} mimetype - The MIME type of the stream
* @returns a yielded mimeType attribute
*/
*createAdaptationSet(mimetype = 'video/webm') {
const as = this.doc.createElement('AdaptationSet')
as.setAttribute('mimeType', mimetype)
while(true) {
yield as;
}
}
/**
*
* @param {string} contentType - The content type of the media being streams
* @param {integer} id - The id of the content component
*/
*createContentComponent(contentType = 'video', id = 1) {
const cc = this.doc.createElement('ContentComponent');
cc.setAttribute('contentType', contentType);
while(true) {
console.log(id)
cc.setAttribute('id', id);
id++;
yield cc;
}
}
/**
*
* @param {Buffer} videoData - videoData to be streamed for initialization
* @param {integer} timescale - The timescale of the media in microseconds
* @param {integer} duration - The duration of the media in microseconds
* @param {integer} startNumber - The start number of the media content
* @param {string} media - The media URL for update PUTs
*/
*createSegmentTemplate (videoData, timescale = 1000, duration = 2000, startNumber = 1, media = '') {
const st = this.doc.createElement('SegmentTemplate')
st.setAttribute('startNumber', startNumber)
st.setAttribute('duration', duration)
st.setAttribute('timescale', timescale)
st.setAttribute('media', media)
while (true) {
st.setAttribute('initialization', "data:video/webm;base64," + btoa(videoData))
yield st;
}
}
/**
*
* @returns {string} str - XML string representation of the manifest
*/
getXMLString() {
const str = this.serializer.serializeToString(this.mpd)
return str
}
/**
*
* @returns {File} file - A new File named init.mpd which contains the manifest XML
*/
getXMLFile() {
const file = new File([this.getXMLString()], 'init.mpd', {
type: 'text/xml'
})
return file
}
}
export {
MPD
}