forked from aadsm/node-id3
/
flac.js
79 lines (65 loc) · 2.23 KB
/
flac.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
var strtok = require('strtok');
var fs = require('fs');
var common = require('./common');
var Flac = module.exports = function(stream) {
this.stream = stream;
this.parse();
};
Flac.prototype = new process.EventEmitter();
Flac.prototype.parse = function() {
var self = this;
strtok.parse(self.stream, function(v, cb) {
try {
if (!v) {
cb.position = 'ID';
return new strtok.StringType(4);
}
if (cb.position === 'ID') {
if (v !== 'fLaC') {
throw new Error('expected flac header but was not found');
}
cb.position = 'METADATA_BLOCK_HEADER';
return new strtok.BufferType(4);
}
if (cb.position === 'METADATA_BLOCK_HEADER') {
cb.blockHeader = {
last_metadata_block : (v[0] & 0x80) == 0x80,
block_type : v[0] & 0x7f,
length : strtok.UINT24_BE.get(v, 1)
}
if (cb.blockHeader.last_metadata_block) {
self.emit('done');
return strtok.DONE;
}
cb.position = 'METADATA_BLOCK_DATA';
return new strtok.BufferType(cb.blockHeader.length);
}
if (cb.position === 'METADATA_BLOCK_DATA') {
if (cb.blockHeader.block_type === 4) {
var offset = 0;
var vendorLen = strtok.UINT32_LE.get(v, offset);
offset += 4;
var vendorString = v.toString('utf8', offset, offset += vendorLen);
var commentListLength = strtok.UINT32_LE.get(v, offset);
offset += 4;
for (var i=0; i < commentListLength; i++) {
var len = strtok.UINT32_LE.get(v, offset);
offset += 4;
var comment = v.toString('utf8', offset, offset += len);
var split = comment.split('=');
self.emit(split[0].toUpperCase(), split[1]);
}
}
if (cb.blockHeader.block_type === 6) {
var picture = common.readVorbisPicture(v);
self.emit('METADATA_BLOCK_PICTURE', picture);
}
cb.position = 'METADATA_BLOCK_HEADER';
return new strtok.BufferType(4);
}
} catch (exception) {
self.emit('done', exception);
return strtok.DONE;
}
});
};