Bladeren bron

duration.js -> probe.js

Noah 7 jaren geleden
bovenliggende
commit
01145fc1e2
9 gewijzigde bestanden met toevoegingen van 89 en 91 verwijderingen
  1. 0 35
      audiogram/duration.js
  2. 9 8
      audiogram/index.js
  3. 43 0
      audiogram/probe.js
  4. 3 3
      audiogram/trim.js
  5. 2 2
      client/index.js
  6. 1 0
      client/waveform.js
  7. 1 1
      package.json
  8. 1 1
      server/status.js
  9. 29 41
      test/duration-test.js

+ 0 - 35
audiogram/duration.js Bestand weergeven

1
-var probe = require("node-ffprobe");
2
-
3
-module.exports = function(filename, cb){
4
-
5
-  probe(filename, function(err, probeData) {
6
-
7
-    if (err) {
8
-      return cb(err);
9
-    }
10
-
11
-    var duration = getDuration(probeData);
12
-
13
-    if (!duration || duration === "N/A" || !(duration > 0)) {
14
-      return cb("Couldn't probe audio duration.");
15
-    }
16
-
17
-    return cb(null, duration);
18
-
19
-  });
20
-
21
-};
22
-
23
-function getDuration(probeData) {
24
-
25
-  if (probeData.format && probeData.format.duration) {
26
-    return probeData.format.duration;
27
-  }
28
-
29
-  if (Array.isArray(probeData.streams) && probeData.streams.length && probeData.streams[0].duration) {
30
-    return probeData.streams[0].duration;
31
-  }
32
-
33
-  return null;
34
-
35
-}

+ 9 - 8
audiogram/index.js Bestand weergeven

5
     serverSettings = require("../settings/"),
5
     serverSettings = require("../settings/"),
6
     transports = require("../lib/transports/"),
6
     transports = require("../lib/transports/"),
7
     logger = require("../lib/logger/"),
7
     logger = require("../lib/logger/"),
8
-    getDuration = require("./duration.js"),
8
+    probe = require("./probe.js"),
9
     getWaveform = require("./waveform.js"),
9
     getWaveform = require("./waveform.js"),
10
     initializeCanvas = require("./initialize-canvas.js"),
10
     initializeCanvas = require("./initialize-canvas.js"),
11
     drawFrames = require("./draw-frames.js"),
11
     drawFrames = require("./draw-frames.js"),
29
 
29
 
30
 }
30
 }
31
 
31
 
32
-// Probe an audio file for its duration, compute the number of frames required
33
-Audiogram.prototype.getDuration = function(cb) {
32
+// Probe an audio file for its duration and # of channels, compute the number of frames required
33
+Audiogram.prototype.probe = function(cb) {
34
 
34
 
35
   var self = this;
35
   var self = this;
36
 
36
 
37
-  this.status("duration");
37
+  this.status("probing");
38
 
38
 
39
-  getDuration(this.audioPath, function(err, duration){
39
+  probe(this.audioPath, function(err, data){
40
 
40
 
41
     if (err) {
41
     if (err) {
42
       return cb(err);
42
       return cb(err);
43
     }
43
     }
44
 
44
 
45
-    if (self.settings.maxDuration && self.settings.maxDuration < duration) {
45
+    if (self.settings.maxDuration && self.settings.maxDuration < data.duration) {
46
       cb("Exceeds max duration of " + self.settings.maxDuration + "s");
46
       cb("Exceeds max duration of " + self.settings.maxDuration + "s");
47
     }
47
     }
48
 
48
 
49
-    self.set("numFrames", self.numFrames = Math.floor(duration * self.settings.framesPerSecond));
49
+    self.set("numFrames", self.numFrames = Math.floor(data.duration * self.settings.framesPerSecond));
50
+    self.channels = data.channels;
50
 
51
 
51
     cb(null);
52
     cb(null);
52
 
53
 
160
   }
161
   }
161
 
162
 
162
   // Get the audio's duration for computing number of frames
163
   // Get the audio's duration for computing number of frames
163
-  q.defer(this.getDuration.bind(this));
164
+  q.defer(this.probe.bind(this));
164
 
165
 
165
   // Get the audio waveform data
166
   // Get the audio waveform data
166
   q.defer(this.getWaveform.bind(this));
167
   q.defer(this.getWaveform.bind(this));

+ 43 - 0
audiogram/probe.js Bestand weergeven

1
+var probe = require("node-ffprobe");
2
+
3
+module.exports = function(filename, cb){
4
+
5
+  probe(filename, function(err, probeData) {
6
+
7
+    if (err) {
8
+      return cb(err);
9
+    }
10
+
11
+    var duration = getProperty(probeData, "duration"),
12
+        channels = getProperty(probeData, "channels");
13
+
14
+    if (!duration || duration === "N/A" || !(duration > 0)) {
15
+      return cb("Couldn't probe audio duration.");
16
+    }
17
+
18
+    if (typeof channels !== "number" || channels < 1 || channels > 2) {
19
+      return cb("Couldn't detect mono/stereo channels");
20
+    }
21
+
22
+    return cb(null, {
23
+      duration: duration,
24
+      channels: channels
25
+    });
26
+
27
+  });
28
+
29
+};
30
+
31
+function getProperty(probeData, property) {
32
+
33
+  if (probeData.format && probeData.format[property]) {
34
+    return probeData.format[property];
35
+  }
36
+
37
+  if (Array.isArray(probeData.streams) && probeData.streams.length && probeData.streams[0][property]) {
38
+    return probeData.streams[0][property];
39
+  }
40
+
41
+  return null;
42
+
43
+}

+ 3 - 3
audiogram/trim.js Bestand weergeven

1
 var exec = require("child_process").exec,
1
 var exec = require("child_process").exec,
2
-    getDuration = require("./duration.js");
2
+    probe = require("./probe.js");
3
 
3
 
4
 function trimAudio(options, cb) {
4
 function trimAudio(options, cb) {
5
 
5
 
6
   if (!options.endTime) {
6
   if (!options.endTime) {
7
 
7
 
8
-    return getDuration(options.origin, function(err, duration){
8
+    return probe(options.origin, function(err, data){
9
       if (err) {
9
       if (err) {
10
         return cb(err);
10
         return cb(err);
11
       }
11
       }
12
 
12
 
13
-      options.endTime = duration;
13
+      options.endTime = data.duration;
14
       trimAudio(options, cb);
14
       trimAudio(options, cb);
15
 
15
 
16
     });
16
     });

+ 2 - 2
client/index.js Bestand weergeven

266
       return "Downloading audio for processing";
266
       return "Downloading audio for processing";
267
     case "trim":
267
     case "trim":
268
       return "Trimming audio";
268
       return "Trimming audio";
269
-    case "duration":
270
-      return "Checking duration";
269
+    case "probing":
270
+      return "Probing audio file";
271
     case "waveform":
271
     case "waveform":
272
       return "Analyzing waveform";
272
       return "Analyzing waveform";
273
     case "renderer":
273
     case "renderer":

+ 1 - 0
client/waveform.js Bestand weergeven

38
   var fileReader = new FileReader();
38
   var fileReader = new FileReader();
39
 
39
 
40
   var close = function(err, data) {
40
   var close = function(err, data) {
41
+    console.warn(err);
41
     ctx.close();
42
     ctx.close();
42
     cb(err, data);
43
     cb(err, data);
43
   };
44
   };

+ 1 - 1
package.json Bestand weergeven

25
   "dependencies": {
25
   "dependencies": {
26
     "aws-sdk": "^2.2.39",
26
     "aws-sdk": "^2.2.39",
27
     "browserify": "^13.0.0",
27
     "browserify": "^13.0.0",
28
+    "canvas": "git+https://github.com/chearon/node-canvas.git#b62dd3a9fa",
28
     "compression": "^1.6.1",
29
     "compression": "^1.6.1",
29
     "d3": "^4.1.1",
30
     "d3": "^4.1.1",
30
     "dotenv": "^2.0.0",
31
     "dotenv": "^2.0.0",
39
     "rimraf": "^2.5.0",
40
     "rimraf": "^2.5.0",
40
     "smartquotes": "^1.0.0",
41
     "smartquotes": "^1.0.0",
41
     "underscore": "^1.8.3",
42
     "underscore": "^1.8.3",
42
-    "canvas": "git+https://github.com/chearon/node-canvas.git#b62dd3a9fa",
43
     "waveform": "git+https://github.com/veltman/node-waveform.git#8b1a22f109",
43
     "waveform": "git+https://github.com/veltman/node-waveform.git#8b1a22f109",
44
     "webaudio-peaks": "0.0.5",
44
     "webaudio-peaks": "0.0.5",
45
     "winston": "^2.2.0"
45
     "winston": "^2.2.0"

+ 1 - 1
server/status.js Bestand weergeven

30
         hash = { status: "unknown" };
30
         hash = { status: "unknown" };
31
       }
31
       }
32
 
32
 
33
-      ["duration","numFrames","framesComplete"].forEach(function(key) {
33
+      ["numFrames", "framesComplete"].forEach(function(key) {
34
         if (key in hash) {
34
         if (key in hash) {
35
           hash[key] = +hash[key];
35
           hash[key] = +hash[key];
36
         }
36
         }

+ 29 - 41
test/duration-test.js Bestand weergeven

5
 
5
 
6
 require("mkdirp").sync(path.join(__dirname, "tmp"));
6
 require("mkdirp").sync(path.join(__dirname, "tmp"));
7
 
7
 
8
-var getDuration = require("../audiogram/duration.js"),
8
+var probe = require("../audiogram/probe.js"),
9
     trimAudio = require("../audiogram/trim.js");
9
     trimAudio = require("../audiogram/trim.js");
10
 
10
 
11
-tape("MP3 duration", function(test) {
11
+tape("MP3 probe", function(test) {
12
 
12
 
13
-  getDuration(path.join(__dirname, "data/glazed-donut.mp3"), function(err, duration){
13
+  probe(path.join(__dirname, "data/glazed-donut.mp3"), function(err, data){
14
 
14
 
15
     test.error(err);
15
     test.error(err);
16
-    test.equal(typeof duration, "number");
17
-    test.assert(Math.abs(duration - 26.67) < 0.1);
16
+    test.equal(typeof data.duration, "number");
17
+    test.equal(data.channels, 2);
18
+    test.assert(Math.abs(data.duration - 26.67) < 0.1);
18
     test.end();
19
     test.end();
19
 
20
 
20
   });
21
   });
21
 
22
 
22
 });
23
 });
23
 
24
 
24
-tape("WAV duration", function(test) {
25
+tape("WAV probe", function(test) {
25
 
26
 
26
-  getDuration(path.join(__dirname, "data/glazed-donut.wav"), function(err, duration){
27
+  probe(path.join(__dirname, "data/glazed-donut.wav"), function(err, data){
27
 
28
 
28
     test.error(err);
29
     test.error(err);
29
-    test.equal(typeof duration, "number");
30
-    test.assert(Math.abs(duration - 1.83) < 0.1);
30
+    test.equal(typeof data.duration, "number");
31
+    test.equal(data.channels, 2);
32
+    test.assert(Math.abs(data.duration - 1.83) < 0.1);
31
     test.end();
33
     test.end();
32
 
34
 
33
   });
35
   });
34
 
36
 
35
 });
37
 });
36
 
38
 
37
-tape("Duration error", function(test) {
39
+tape("Probe error", function(test) {
38
 
40
 
39
-  getDuration(path.join(__dirname, "..", "README.md"), function(err){
41
+  probe(path.join(__dirname, "..", "README.md"), function(err){
40
 
42
 
41
     test.ok(err);
43
     test.ok(err);
42
     test.end();
44
     test.end();
55
 
57
 
56
   queue(1)
58
   queue(1)
57
     .defer(trimAudio, options)
59
     .defer(trimAudio, options)
58
-    .defer(getDuration, options.destination)
59
-    .await(function(err, _, duration){
60
+    .defer(probe, options.destination)
61
+    .await(function(err, _, data){
60
 
62
 
61
       test.error(err);
63
       test.error(err);
62
-      test.equal(typeof duration, "number");
63
-      test.assert(Math.abs(duration - 20) < 0.1);
64
+      test.equal(typeof data.duration, "number");
65
+      test.assert(Math.abs(data.duration - 20) < 0.1);
64
       test.end();
66
       test.end();
65
 
67
 
66
     });
68
     });
77
 
79
 
78
   queue(1)
80
   queue(1)
79
     .defer(trimAudio, options)
81
     .defer(trimAudio, options)
80
-    .defer(getDuration, options.destination)
81
-    .await(function(err, _, duration){
82
+    .defer(probe, options.destination)
83
+    .await(function(err, _, data){
82
 
84
 
83
       test.error(err);
85
       test.error(err);
84
-      test.equal(typeof duration, "number");
85
-      test.assert(Math.abs(duration - 20) < 0.1);
86
+      test.equal(typeof data.duration, "number");
87
+      test.assert(Math.abs(data.duration - 20) < 0.1);
86
       test.end();
88
       test.end();
87
 
89
 
88
     });
90
     });
100
 
102
 
101
   queue(1)
103
   queue(1)
102
     .defer(trimAudio, options)
104
     .defer(trimAudio, options)
103
-    .defer(getDuration, options.destination)
104
-    .await(function(err, _, duration){
105
+    .defer(probe, options.destination)
106
+    .await(function(err, _, data){
105
 
107
 
106
       test.error(err);
108
       test.error(err);
107
-      test.equal(typeof duration, "number");
108
-      test.assert(Math.abs(duration - 5) < 0.1);
109
+      test.equal(typeof data.duration, "number");
110
+      test.assert(Math.abs(data.duration - 5) < 0.1);
109
       test.end();
111
       test.end();
110
 
112
 
111
     });
113
     });
122
     endTime: 4
124
     endTime: 4
123
   };
125
   };
124
 
126
 
125
-  queue(1)
126
-    .defer(trimAudio, options)
127
-    .defer(getDuration, options.destination)
128
-    .await(function(err, _, duration){
129
-
130
-      test.ok(err);
131
-      test.end();
132
-
133
-    });
134
-
135
-});
136
-
137
-// Cleanup
138
-tape.onFinish(function(){
139
-  require("rimraf")(path.join(__dirname, "tmp"), function(err){
140
-    if (err) {
141
-      throw err;
142
-    }
127
+  trimAudio(options, function(err){
128
+    test.ok(err);
129
+    test.end();
143
   });
130
   });
131
+
144
 });
132
 });
145
 
133
 
146
 // Cleanup
134
 // Cleanup