Skip to content

Commit 3ac2a21

Browse files
committed
pcm data tests
1 parent ec4c51e commit 3ac2a21

File tree

4 files changed

+536
-7
lines changed

4 files changed

+536
-7
lines changed

bootstrap.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var AudioDataAnalyzer = require('./library/audio_data_analyzer').analyzer;
1+
var AudioDataAnalyzer = require('./library/audioDataAnalyzer').analyzer;
22

3-
var TrackDownloader = require('./library/track_downloader').downloader;
3+
var TrackDownloader = require('./library/trackDownloader').downloader;
44

55
var http = require('http');
66

@@ -26,8 +26,9 @@ http.createServer(function (request, response) {
2626
response.end();
2727
});
2828
break;
29-
case 'getwavedata':
30-
getWaveData();
29+
case '/getwavedata':
30+
var trackId = '415208';
31+
getWaveData(trackId);
3132
break;
3233
default:
3334
response.writeHead(404, { 'Content-Type': 'text/html' });
@@ -39,7 +40,7 @@ http.createServer(function (request, response) {
3940

4041
console.log('server is listening, ip: ' + serverIp + ', port: ' + serverPort);
4142

42-
var getWaveData = function getWaveDataFunction() {
43+
var getWaveData = function getWaveDataFunction(trackId) {
4344

4445
var audioDataAnalyzer = new AudioDataAnalyzer();
4546

@@ -48,11 +49,11 @@ var getWaveData = function getWaveDataFunction() {
4849
var temporaryTracksDirecotry = './downloaded_tracks';
4950
var format = 'ogg';
5051

51-
trackDownloader.writeTrackToDisc(415208, function writeTrackCallback(error, trackPath) {
52+
trackDownloader.writeTrackToDisc(trackId, function writeTrackCallback(error, trackPath) {
5253

5354
if (!error) {
5455

55-
audioDataAnalyzer.getValues(trackPath, function getValuesCallback(error, values) {
56+
audioDataAnalyzer.getPCMValues(trackPath, function getValuesCallback(error, values) {
5657

5758
if (!error) {
5859

library/audioDataAnalyzer.js

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
2+
// nodejs child_process
3+
var childProcess = require('child_process');
4+
5+
/**
6+
*
7+
* @returns {analyzerConstructor}
8+
*/
9+
var analyzer = function analyzerConstructor() {
10+
11+
};
12+
13+
/**
14+
*
15+
* get track data using ffprobe (channels, samplerate, ...)
16+
*
17+
* @param {type} trackPath
18+
* @param {type} callback
19+
* @returns {undefined}
20+
*/
21+
analyzer.prototype.getData = function getDataFunction(trackPath, callback) {
22+
23+
// ffprobe file data
24+
var ffprobeSpawn = childProcess.spawn(
25+
'ffprobe',
26+
[
27+
trackPath,
28+
'-v',
29+
'quiet',
30+
'-show_streams',
31+
'-show_format',
32+
'-print_format',
33+
'json'
34+
]
35+
);
36+
37+
var stdoutOuputString = '';
38+
var stderrOuputString = '';
39+
40+
ffprobeSpawn.stdout.on('data', function(data) {
41+
42+
stdoutOuputString += data;
43+
44+
});
45+
46+
var trackData = {};
47+
48+
ffprobeSpawn.stdout.on('end', function(data) {
49+
50+
console.log('ffprobeSpawn stdout end');
51+
52+
if (stdoutOuputString !== '') {
53+
54+
console.log('stdoutOuput');
55+
//console.log(stdoutOuputString);
56+
57+
var stdoutOuput = JSON.parse(stdoutOuputString);
58+
59+
trackData.duration = stdoutOuput['format']['duration'];
60+
trackData.size = stdoutOuput['format']['size'];
61+
trackData.bitRate = stdoutOuput['format']['bit_rate'];
62+
trackData.sampleRate = stdoutOuput['streams'][0]['sample_rate'];
63+
trackData.channels = stdoutOuput['streams'][0]['channels'];
64+
65+
}
66+
67+
});
68+
69+
ffprobeSpawn.stderr.setEncoding('utf8');
70+
71+
ffprobeSpawn.stderr.on('data', function(data) {
72+
73+
stderrOuputString += data;
74+
75+
});
76+
77+
ffprobeSpawn.stderr.on('end', function() {
78+
79+
console.log('ffprobeSpawn stderr end');
80+
81+
});
82+
83+
ffprobeSpawn.on('exit', function(code) {
84+
85+
console.log('ffprobeSpawn exit, code: ' + code);
86+
87+
if (code > 0) {
88+
89+
callback(stderrOuputString);
90+
91+
} else {
92+
93+
if (Object.keys(trackData).length > 0) {
94+
95+
callback(false, trackData);
96+
97+
} else {
98+
99+
callback('ffprobe did not output any data');
100+
101+
}
102+
103+
}
104+
105+
});
106+
107+
ffprobeSpawn.on('close', function() {
108+
109+
console.log('ffprobeSpawn close');
110+
111+
});
112+
113+
};
114+
115+
/**
116+
*
117+
* get pcm data of a track
118+
*
119+
* @param {type} trackPath
120+
* @param {type} callback
121+
* @returns {undefined}
122+
*/
123+
analyzer.prototype.getPCMValues = function getValuesFunction(trackPath, callback) {
124+
125+
this.getData(trackPath, function(error, trackData) {
126+
127+
if (!error) {
128+
129+
console.log('ffprobe track data: ');
130+
console.log(trackData);
131+
132+
// get audio pcm
133+
var ffmpegSpawn = childProcess.spawn(
134+
'ffmpeg',
135+
[
136+
'-i',
137+
trackPath,
138+
'-f',
139+
's16le',
140+
'-ac',
141+
trackData.channels,
142+
'-acodec',
143+
'pcm_s16le',
144+
'-ar',
145+
trackData.sampleRate,
146+
'-y',
147+
'pipe:1'
148+
]
149+
);
150+
151+
var stdoutOuputString = '';
152+
var stderrOuputString = '';
153+
154+
// TODO: uncomment for ffprobe
155+
//ffmpegSpawn.stdout.setEncoding('utf8');
156+
157+
var oddByte = null;
158+
var channel = 0;
159+
160+
//var outputCounter = 0;
161+
162+
var maxValue = 0;
163+
164+
//var output = [];
165+
166+
//var counter = 0;
167+
168+
ffmpegSpawn.stdout.on('data', function(data) {
169+
170+
// http://nodejs.org/api/buffer.html#buffer_buf_readint16le_offset_noassert
171+
// https://github.com/jhurliman/node-pcm/blob/master/lib/pcm.js
172+
173+
var value;
174+
var i;
175+
var dataLen = data.length;
176+
var percentageOfMax = 0;
177+
178+
//counter++;
179+
180+
for (i=0; i < dataLen; i += 2) {
181+
182+
value = data.readInt16LE(i, true);
183+
184+
//channel = ++channel % 2;
185+
186+
//console.log('B: ' + value + ' / ' + channel);
187+
188+
//outputCounter++;
189+
190+
//if (value > maxValue) maxValue = value;
191+
192+
// maxValue is 32767
193+
194+
// (value / maxValue)*100 = percentage of max
195+
percentageOfMax = (value / 32767)*100;
196+
197+
//return false;
198+
199+
//outputCounter++;
200+
201+
}
202+
203+
console.log(i);
204+
205+
//console.log('outputCounter: ' + outputCounter);
206+
207+
//console.log(maxValue); // 32767
208+
209+
// get absolute value
210+
//var absolutePercentageOfMaxMath = Math.abs(percentageOfMax);
211+
212+
//output.push(absolutePercentageOfMaxMath);
213+
214+
//console.log(absolutePercentageOfMaxMath);
215+
216+
/*var bar = '';
217+
218+
for (i=0; i < absolutePercentageOfMaxMath/10; i++) {
219+
220+
bar += '*';
221+
222+
}*/
223+
224+
//console.log(bar);
225+
226+
});
227+
228+
ffmpegSpawn.stdout.on('end', function(data) {
229+
230+
console.log('ffmpegSpawn stdout end');
231+
//console.log(counter);
232+
//console.log(outputCounter);
233+
234+
if (output.length > 0) {
235+
236+
callback(false, output);
237+
238+
} else {
239+
240+
callback('no output recieved');
241+
242+
}
243+
244+
});
245+
246+
ffmpegSpawn.stderr.setEncoding('utf8');
247+
248+
ffmpegSpawn.stderr.on('data', function(data) {
249+
250+
//console.log(data.toString());
251+
252+
});
253+
254+
ffmpegSpawn.stderr.on('end', function() {
255+
256+
console.log('ffmpegSpawn stderr end');
257+
258+
});
259+
260+
ffmpegSpawn.on('exit', function(code) {
261+
262+
console.log('ffmpegSpawn exit, code: ' + code);
263+
264+
});
265+
266+
ffmpegSpawn.on('close', function() {
267+
268+
console.log('ffmpegSpawn close');
269+
270+
});
271+
272+
} else {
273+
274+
callback(error);
275+
276+
}
277+
278+
});
279+
280+
};
281+
282+
module.exports.analyzer = analyzer;

library/fileManager.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// nodejs fs
2+
var fs = require('fs');
3+
4+
/**
5+
*
6+
* @returns {fileManagerConstructor}
7+
*/
8+
var fileManager = function fileManagerConstructor() {
9+
10+
};
11+
12+
/**
13+
*
14+
* does the file exist
15+
*
16+
* @param {type} file
17+
* @param {type} callback
18+
* @returns {undefined}
19+
*/
20+
fileManager.prototype.exists = function fileExistsFunction(file, callback) {
21+
22+
console.log('file exists: ' + file);
23+
24+
if (callback !== undefined) {
25+
26+
// async exists
27+
fs.exists(file, function(exists) {
28+
29+
callback(false, exists);
30+
31+
});
32+
33+
} else {
34+
35+
fs.existsSync(file);
36+
37+
}
38+
39+
};
40+
41+
module.exports.fileManager = fileManager;

0 commit comments

Comments
 (0)