Przeglądaj źródła

Added .duration and .frameCount, populated when for seekable video

Dominic Szablewski 10 lat temu
rodzic
commit
5ac302b3bd
2 zmienionych plików z 18 dodań i 36 usunięć
  1. 8 10
      README.md
  2. 10 26
      jsmpg.js

+ 8 - 10
README.md Wyświetl plik

42
 player.seekToFrame(1200, true); // Seek to frame 1200 exactly
42
 player.seekToFrame(1200, true); // Seek to frame 1200 exactly
43
 
43
 
44
 
44
 
45
+// Passing 'seekable: true' also populates the total frame count and duration
46
+// of the video
47
+
48
+console.log('Duration: '+player.duration+' seconds ('+frames+' player.frameCount)')
49
+
50
+
51
+
45
 // An 'onload' callback can be specified in the 'options' argument
52
 // An 'onload' callback can be specified in the 'options' argument
46
 var mpegLoaded = function( player ) {
53
 var mpegLoaded = function( player ) {
47
 	console.log('Loaded', player);
54
 	console.log('Loaded', player);
48
-	
49
-	// calculateFrameCount() and calculateDuration() can only be called
50
-	// after the mpeg has been fully loaded. So this callback is the ideal
51
-	// place to fetch this info
52
-	var frames = player.calculateFrameCount(),
53
-		duration = player.calculateDuration();
54
-		
55
-	console.log('Duration: '+duration+' seconds ('+frames+' frames)');
56
 };
55
 };
57
-
58
-var player = new jsmpeg('file.mpeg', {onload:mpegLoaded});
56
+var player = new jsmpeg('file.mpeg', {onload: mpegLoaded});
59
 
57
 
60
 // If you don't use 'autoplay' and don't explicitly call .play(), you can get individual
58
 // If you don't use 'autoplay' and don't explicitly call .play(), you can get individual
61
 // video frames (a canvas element) like so:
59
 // video frames (a canvas element) like so:

+ 10 - 26
jsmpg.js Wyświetl plik

268
 // Loading via Ajax
268
 // Loading via Ajax
269
 
269
 
270
 jsmpeg.prototype.intraFrames = [];
270
 jsmpeg.prototype.intraFrames = [];
271
+jsmpeg.prototype.frameCount = 0;
272
+jsmpeg.prototype.duration = 0;
271
 	
273
 	
272
 jsmpeg.prototype.load = function( url ) {
274
 jsmpeg.prototype.load = function( url ) {
273
 	this.url = url;
275
 	this.url = url;
320
 	this.firstSequenceHeader = this.buffer.index;
322
 	this.firstSequenceHeader = this.buffer.index;
321
 	this.decodeSequenceHeader();
323
 	this.decodeSequenceHeader();
322
 
324
 
325
+	// Calculate the duration. This only works if the video is seekable and we have a frame count.
326
+	this.duration = this.frameCount / this.pictureRate;
327
+
323
 	// Load the first frame
328
 	// Load the first frame
324
 	this.nextFrame();
329
 	this.nextFrame();
325
 	
330
 	
334
 
339
 
335
 jsmpeg.prototype.collectIntraFrames = function() {
340
 jsmpeg.prototype.collectIntraFrames = function() {
336
 	// Loop through the whole buffer and collect all intraFrames to build our seek index.
341
 	// Loop through the whole buffer and collect all intraFrames to build our seek index.
337
-	for( var frame = 0; this.findStartCode(START_PICTURE) !== BitReader.NOT_FOUND; frame++ ) {
342
+	// We also keep track of total frame count here
343
+	var frame;
344
+	for( frame = 0; this.findStartCode(START_PICTURE) !== BitReader.NOT_FOUND; frame++ ) {
338
 
345
 
339
 		// Check if the found picture is an intra frame and remember the position
346
 		// Check if the found picture is an intra frame and remember the position
340
 		this.buffer.advance(10); // skip temporalReference
347
 		this.buffer.advance(10); // skip temporalReference
343
 			this.intraFrames.push({frame: frame, index: this.buffer.index - 13});
350
 			this.intraFrames.push({frame: frame, index: this.buffer.index - 13});
344
 		}
351
 		}
345
 	}
352
 	}
353
+
354
+	this.frameCount = frame;
346
 };
355
 };
347
 
356
 
348
 jsmpeg.prototype.seekToFrame = function(seekFrame, seekExact) {	
357
 jsmpeg.prototype.seekToFrame = function(seekFrame, seekExact) {	
430
 	}
439
 	}
431
 };
440
 };
432
 
441
 
433
-jsmpeg.prototype.cachedFrameCount = 0;
434
-jsmpeg.prototype.calculateFrameCount = function() {
435
-	if( !this.buffer || this.cachedFrameCount ) { 
436
-		return this.cachedFrameCount; 
437
-	}
438
-	
439
-	// Remember the buffer position, so we can rewind to the beginning and 
440
-	// reset to the current position afterwards
441
-	var currentPlaybackIndex = this.buffer.index,
442
-		frames = 0;
443
-	
444
-	this.buffer.index = 0;
445
-	while( this.findStartCode(START_PICTURE) !== BitReader.NOT_FOUND ) {
446
-		frames++;
447
-	}
448
-	this.buffer.index = currentPlaybackIndex;
449
-	
450
-	this.cachedFrameCount = frames;
451
-	return frames;
452
-};
453
-
454
-jsmpeg.prototype.calculateDuration = function() {
455
-	return this.calculateFrameCount() * (1/this.pictureRate);
456
-};
457
-
458
 
442
 
459
 
443
 
460
 // ----------------------------------------------------------------------------
444
 // ----------------------------------------------------------------------------