ssv/ssv/static/js/dist/ssv.bundle.js
// detailed once i finish writing the code
detailed once i finish writing the code
detailed once i finish writing the code
function toWebM(frames, outputAsArray) {
		var info = checkFrames(frames);
		var CLUSTER_MAX_DURATION = 30000;
		var EBML = [{
			"id": 0x1a45dfa3, 
			"data": [{
				"data": 1,
				"id": 0x4286 Version
			}, {
				"data": 1,
				"id": 0x42f7 ReadVersion
			}, {
				"data": 4,
				"id": 0x42f2 MaxIDLength
			}, {
				"data": 8,
				"id": 0x42f3 MaxSizeLength
			}, {
				"data": "webm",
				"id": 0x4282 
			}, {
				"data": 2,
				"id": 0x4287 Version
			}, {
				"data": 2,
				"id": 0x4285 ReadVersion
			}]
		}, {
			"id": 0x18538067, 
			"data": [{
				"id": 0x1549a966, 
				"data": [{
					"data": 1e6, 
					"id": 0x2ad7b1 
				}, {
					"data": "whammy",
					"id": 0x4d80 
				}, {
					"data": "whammy",
					"id": 0x5741 
				}, {
					"data": doubleToString(info.duration),
					"id": 0x4489 
				}]
			}, {
				"id": 0x1654ae6b, 
				"data": [{
					"id": 0xae, 
					"data": [{
						"data": 1,
						"id": 0xd7 
					}, {
						"data": 1,
						"id": 0x73c5 
					}, {
						"data": 0,
						"id": 0x9c 
					}, {
						"data": "und",
						"id": 0x22b59c 
					}, {
						"data": "V_VP8",
						"id": 0x86 
					}, {
						"data": "VP8",
						"id": 0x258688 
					}, {
						"data": 1,
						"id": 0x83 
					}, {
						"id": 0xe0, 
						"data": [{
							"data": info.width,
							"id": 0xb0 
						}, {
							"data": info.height,
							"id": 0xba 
						}]
					}]
				}]
			}, {
				"id": 0x1c53bb6b, 
				"data": [
				]
			}
			]
		}];
		var segment = EBML[1];
		var cues = segment.data[2];
		var frameNumber = 0;
		var clusterTimecode = 0;
		while (frameNumber < frames.length) {
			var cuePoint = {
				"id": 0xbb, 
				"data": [{
					"data": Math.round(clusterTimecode),
					"id": 0xb3 
				}, {
					"id": 0xb7, 
					"data": [{
						"data": 1,
						"id": 0xf7 
					}, {
						"data": 0, 
						"size": 8,
						"id": 0xf1 
					}]
				}]
			};
			cues.data.push(cuePoint);
			var clusterFrames = [];
			var clusterDuration = 0;
			do {
				clusterFrames.push(frames[frameNumber]);
				clusterDuration += frames[frameNumber].duration;
				frameNumber++;
			} while (frameNumber < frames.length && clusterDuration < CLUSTER_MAX_DURATION);
			var clusterCounter = 0;
			var cluster = {
				"id": 0x1f43b675, 
				"data": [{
					"data": Math.round(clusterTimecode),
					"id": 0xe7 
				}].concat(clusterFrames.map(function (webp) {
					var block = makeSimpleBlock({
						discardable: 0,
						frame: webp.data.slice(4),
						invisible: 0,
						keyframe: 1,
						lacing: 0,
						trackNum: 1,
						timecode: Math.round(clusterCounter)
					});
					clusterCounter += webp.duration;
					return {
						data: block,
						id: 0xa3
					};
				}))
			};
			segment.data.push(cluster);
			clusterTimecode += clusterDuration;
		}
		var position = 0;
		for (var i = 0; i < segment.data.length; i++) {
			if (i >= 3) {
				cues.data[i - 3].data[1].data[1].data = position;
			}
			var data = generateEBML([segment.data[i]], outputAsArray);
			position += data.size || data.byteLength || data.length;
			if (i != 2) {
				segment.data[i] = data;
			}
		}
		return generateEBML(EBML, outputAsArray);
	}
function toWebM ( frames , outputAsArray ) { var info = checkFrames ( frames ) ; var CLUSTER_MAX_DURATION = 30000 ; var EBML = [ { "id" : 0x1a45dfa3 , "data" : [ { "data" : 1 , "id" : 0x4286 } , { "data" : 1 , "id" : 0x42f7 } , { "data" : 4 , "id" : 0x42f2 } , { "data" : 8 , "id" : 0x42f3 } , { "data" : "webm" , "id" : 0x4282 } , { "data" : 2 , "id" : 0x4287 } , { "data" : 2 , "id" : 0x4285 } ] } , { "id" : 0x18538067 , "data" : [ { "id" : 0x1549a966 , "data" : [ { "data" : 1e6 , "id" : 0x2ad7b1 } , { "data" : "whammy" , "id" : 0x4d80 } , { "data" : "whammy" , "id" : 0x5741 } , { "data" : doubleToString ( info . duration ) , "id" : 0x4489 } ] } , { "id" : 0x1654ae6b , "data" : [ { "id" : 0xae , "data" : [ { "data" : 1 , "id" : 0xd7 } , { "data" : 1 , "id" : 0x73c5 } , { "data" : 0 , "id" : 0x9c } , { "data" : "und" , "id" : 0x22b59c } , { "data" : "V_VP8" , "id" : 0x86 } , { "data" : "VP8" , "id" : 0x258688 } , { "data" : 1 , "id" : 0x83 } , { "id" : 0xe0 , "data" : [ { "data" : info . width , "id" : 0xb0 } , { "data" : info . height , "id" : 0xba } ] } ] } ] } , { "id" : 0x1c53bb6b , "data" : [ ] } ] } ] ; var segment = EBML [ 1 ] ; var cues = segment . data [ 2 ] ; var frameNumber = 0 ; var clusterTimecode = 0 ; while ( frameNumber < frames . length ) { var cuePoint = { "id" : 0xbb , "data" : [ { "data" : Math . round ( clusterTimecode ) , "id" : 0xb3 } , { "id" : 0xb7 , "data" : [ { "data" : 1 , "id" : 0xf7 } , { "data" : 0 , "size" : 8 , "id" : 0xf1 } ] } ] } ; cues . data . push ( cuePoint ) ; var clusterFrames = [ ] ; var clusterDuration = 0 ; do { clusterFrames . push ( frames [ frameNumber ] ) ; clusterDuration += frames [ frameNumber ] . duration ; frameNumber ++ ; } while ( frameNumber < frames . length && clusterDuration < CLUSTER_MAX_DURATION ) ; var clusterCounter = 0 ; var cluster = { "id" : 0x1f43b675 , "data" : [ { "data" : Math . round ( clusterTimecode ) , "id" : 0xe7 } ] . concat ( clusterFrames . map ( function ( webp ) { var block = makeSimpleBlock ( { discardable : 0 , frame : webp . data . slice ( 4 ) , invisible : 0 , keyframe : 1 , lacing : 0 , trackNum : 1 , timecode : Math . round ( clusterCounter ) } ) ; clusterCounter += webp . duration ; return { data : block , id : 0xa3 } ; } ) ) } ; segment . data . push ( cluster ) ; clusterTimecode += clusterDuration ; } var position = 0 ; for ( var i = 0 ; i < segment . data . length ; i ++ ) { if ( i >= 3 ) { cues . data [ i - 3 ] . data [ 1 ] . data [ 1 ] . data = position ; } var data = generateEBML ( [ segment . data [ i ] ] , outputAsArray ) ; position += data . size || data . byteLength || data . length ; if ( i != 2 ) { segment . data [ i ] = data ; } } return generateEBML ( EBML , outputAsArray ) ; }
detailed once i finish writing the code
detailed once i finish writing the code
//max duration by cluster in milliseconds // EBML // EBMLVersion // EBMLReadVersion // EBMLMaxIDLength // EBMLMaxSizeLength // DocType // DocTypeVersion // DocTypeReadVersion // Segment // Info //do things in millisecs (num of nanosecs for duration scale) // TimecodeScale // MuxingApp // WritingApp // Duration // Tracks // TrackEntry // TrackNumber // TrackUID // FlagLacing // Language // CodecID // CodecName // TrackType // Video // PixelWidth // PixelHeight // Cues //cue insertion point //cluster insertion point //Generate clusters (max duration) // CuePoint // CueTime // CueTrackPositions // CueTrack // to be filled in when we know it // CueClusterPosition // Cluster // Timecode //Add cluster to segment //First pass to compute cluster positions // not cues //Save results to avoid having to encode everything twice