Browse Source

Profiling

Noah 7 years ago
parent
commit
6bdad94bc1
3 changed files with 88 additions and 33 deletions
  1. 29 4
      audiogram/index.js
  2. 17 29
      audiogram/waveform.js
  3. 42 0
      lib/profiler.js

+ 29 - 4
audiogram/index.js View File

@@ -5,6 +5,8 @@ var path = require("path"),
5 5
     serverSettings = require("../settings/"),
6 6
     transports = require("../lib/transports/"),
7 7
     logger = require("../lib/logger/"),
8
+    Profiler = require("../lib/profiler.js"),
9
+    probe = require("../lib/probe.js"),
8 10
     getWaveform = require("./waveform.js"),
9 11
     initializeCanvas = require("./initialize-canvas.js"),
10 12
     drawFrames = require("./draw-frames.js"),
@@ -24,6 +26,8 @@ function Audiogram(settings) {
24 26
   this.videoPath = path.join(this.dir, "video.mp4");
25 27
   this.frameDir = path.join(this.dir, "frames");
26 28
 
29
+  this.profiler = new Profiler();
30
+
27 31
   return this;
28 32
 
29 33
 }
@@ -33,13 +37,31 @@ Audiogram.prototype.getWaveform = function(cb) {
33 37
 
34 38
   var self = this;
35 39
 
36
-  this.status("waveform");
40
+  this.status("probing");
41
+
42
+  probe(this.audioPath, function(err, data){
43
+
44
+    if (err) {
45
+      return cb(err);
46
+    }
47
+
48
+    if (self.settings.maxDuration && self.settings.maxDuration < data.duration) {
49
+      return cb("Exceeds max duration of " + self.settings.maxDuration + "s");
50
+    }
51
+
52
+    self.profiler.size(data.duration);
53
+    self.set("numFrames", self.numFrames = Math.floor(data.duration * self.settings.framesPerSecond));
54
+    self.status("waveform");
37 55
 
38
-  getWaveform(this.audioPath, this.settings, function(err, waveform){
56
+    getWaveform(self.audioPath, {
57
+      numFrames: self.numFrames,
58
+      samplesPerFrame: self.settings.samplesPerFrame
59
+    }, function(waveformErr, waveform){
60
+
61
+      return cb(waveformErr, self.settings.waveform = waveform);
39 62
 
40
-    self.set("numFrames", self.numFrames = waveform.length);
63
+    });
41 64
 
42
-    return cb(err, self.settings.waveform = waveform);
43 65
 
44 66
   });
45 67
 
@@ -154,6 +176,8 @@ Audiogram.prototype.render = function(cb) {
154 176
       self.set("url", transports.getURL(self.id));
155 177
     }
156 178
 
179
+    logger.debug(self.profiler.print());
180
+
157 181
     return cb(err);
158 182
 
159 183
   });
@@ -170,6 +194,7 @@ Audiogram.prototype.set = function(field, value) {
170 194
 
171 195
 // Convenience method for .set("status")
172 196
 Audiogram.prototype.status = function(value) {
197
+  this.profiler.start(value);
173 198
   return this.set("status", value);
174 199
 };
175 200
 

+ 17 - 29
audiogram/waveform.js View File

@@ -4,39 +4,27 @@ var probe = require("../lib/probe.js"),
4 4
 
5 5
 function getWaveform(filename, options, cb) {
6 6
 
7
-  probe(filename, function(err, data) {
8
-
9
-    if (err) {
10
-      return cb(err);
11
-    }
12
-
13
-    if (options.maxDuration && options.maxDuration < data.duration) {
14
-      return cb("Exceeds max duration of " + options.maxDuration + "s");
7
+  var stream = pcmStream(filename, {
8
+        channels: options.channels
9
+      }),
10
+      samples = [];
11
+
12
+  stream.on("data",function(sample, channel){
13
+
14
+    // Average multiple channels
15
+    if (channel > 0) {
16
+      samples[samples.length - 1] = ((samples[samples.length - 1] * channel) + sample) / (channel + 1);
17
+    } else {
18
+      samples.push(sample);
15 19
     }
16 20
 
17
-    var stream = pcmStream(filename, {
18
-          channels: options.channels
19
-        }),
20
-        samples = [];
21
-
22
-    stream.on("data",function(sample, channel){
23
-
24
-      // Average multiple channels
25
-      if (channel > 0) {
26
-        samples[samples.length - 1] = ((samples[samples.length - 1] * channel) + sample) / (channel + 1);
27
-      } else {
28
-        samples.push(sample);
29
-      }
30
-
31
-    });
32
-
33
-    stream.on("error", cb);
21
+  });
34 22
 
35
-    stream.on("end", function(output){
36
-      var processed = processSamples(samples, Math.floor(data.duration * options.framesPerSecond), options.samplesPerFrame);
37
-      return cb(null, processed);
38
-    });
23
+  stream.on("error", cb);
39 24
 
25
+  stream.on("end", function(output){
26
+    var processed = processSamples(samples, options.numFrames, options.samplesPerFrame);
27
+    return cb(null, processed);
40 28
   });
41 29
 
42 30
 }

+ 42 - 0
lib/profiler.js View File

@@ -0,0 +1,42 @@
1
+function Profiler() {
2
+  this._times = {};
3
+  return this;
4
+};
5
+
6
+Profiler.prototype.start = function(key) {
7
+  this.end(this._current);
8
+  this._current = key;
9
+  this._times[this._current] = { start: Date.now() };
10
+  return this;
11
+};
12
+
13
+Profiler.prototype.size = function(size) {
14
+  if (!arguments.length) return this._size;
15
+  this._size = size;
16
+  return this;
17
+};
18
+
19
+Profiler.prototype.end = function(key) {
20
+  if (key in this._times) this._times[key].end = Date.now();
21
+  return this;
22
+};
23
+
24
+Profiler.prototype.print = function(size) {
25
+  var rows = [],
26
+      row;
27
+
28
+  this.end(this._current);
29
+
30
+  for (var key in this._times) {
31
+    row = { key: key, time: this._times[key].end - this._times[key].start };
32
+    if (this._size) row.per = row.time / this._size;
33
+    rows.push(row);
34
+  }
35
+
36
+  return rows.map(function(row){
37
+    return row.key + ": " + Math.round(row.time) + "ms total" + (row.per ? ", " + Math.round(row.per) + "ms per" : "");
38
+  }).join("\n");
39
+
40
+};
41
+
42
+module.exports = Profiler;