@lumen5/beamcoder 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.circleci/config.yml +41 -0
  2. package/.circleci/images/testbeam10-4.1/Dockerfile +12 -0
  3. package/.circleci/test_image/Dockerfile +14 -0
  4. package/.circleci/test_image/build.md +13 -0
  5. package/.eslintrc.js +27 -0
  6. package/.github/workflows/publish-npm.yml +33 -0
  7. package/LICENSE +674 -0
  8. package/README.md +1221 -0
  9. package/beamstreams.js +692 -0
  10. package/binding.gyp +103 -0
  11. package/examples/encode_h264.js +92 -0
  12. package/examples/jpeg_app.js +55 -0
  13. package/examples/jpeg_filter_app.js +101 -0
  14. package/examples/make_mp4.js +123 -0
  15. package/images/beamcoder_small.jpg +0 -0
  16. package/index.d.ts +83 -0
  17. package/index.js +44 -0
  18. package/install_ffmpeg.js +240 -0
  19. package/package.json +45 -0
  20. package/scratch/decode_aac.js +38 -0
  21. package/scratch/decode_avci.js +50 -0
  22. package/scratch/decode_hevc.js +38 -0
  23. package/scratch/decode_pcm.js +39 -0
  24. package/scratch/make_a_mux.js +68 -0
  25. package/scratch/muxer.js +74 -0
  26. package/scratch/read_wav.js +35 -0
  27. package/scratch/simple_mux.js +39 -0
  28. package/scratch/stream_avci.js +127 -0
  29. package/scratch/stream_mp4.js +78 -0
  30. package/scratch/stream_mux.js +47 -0
  31. package/scratch/stream_pcm.js +82 -0
  32. package/scratch/stream_wav.js +62 -0
  33. package/scripts/install_beamcoder_dependencies.sh +25 -0
  34. package/src/adaptor.h +202 -0
  35. package/src/beamcoder.cc +937 -0
  36. package/src/beamcoder_util.cc +1129 -0
  37. package/src/beamcoder_util.h +206 -0
  38. package/src/codec.cc +7386 -0
  39. package/src/codec.h +44 -0
  40. package/src/codec_par.cc +1818 -0
  41. package/src/codec_par.h +40 -0
  42. package/src/decode.cc +569 -0
  43. package/src/decode.h +75 -0
  44. package/src/demux.cc +584 -0
  45. package/src/demux.h +88 -0
  46. package/src/encode.cc +496 -0
  47. package/src/encode.h +72 -0
  48. package/src/filter.cc +1888 -0
  49. package/src/filter.h +30 -0
  50. package/src/format.cc +5287 -0
  51. package/src/format.h +77 -0
  52. package/src/frame.cc +2681 -0
  53. package/src/frame.h +52 -0
  54. package/src/governor.cc +286 -0
  55. package/src/governor.h +30 -0
  56. package/src/hwcontext.cc +378 -0
  57. package/src/hwcontext.h +35 -0
  58. package/src/log.cc +186 -0
  59. package/src/log.h +20 -0
  60. package/src/mux.cc +834 -0
  61. package/src/mux.h +106 -0
  62. package/src/packet.cc +762 -0
  63. package/src/packet.h +49 -0
  64. package/test/codecParamsSpec.js +148 -0
  65. package/test/decoderSpec.js +56 -0
  66. package/test/demuxerSpec.js +41 -0
  67. package/test/encoderSpec.js +69 -0
  68. package/test/filtererSpec.js +47 -0
  69. package/test/formatSpec.js +343 -0
  70. package/test/frameSpec.js +145 -0
  71. package/test/introspectionSpec.js +73 -0
  72. package/test/muxerSpec.js +34 -0
  73. package/test/packetSpec.js +122 -0
  74. package/types/Beamstreams.d.ts +98 -0
  75. package/types/Codec.d.ts +123 -0
  76. package/types/CodecContext.d.ts +555 -0
  77. package/types/CodecPar.d.ts +108 -0
  78. package/types/Decoder.d.ts +137 -0
  79. package/types/Demuxer.d.ts +113 -0
  80. package/types/Encoder.d.ts +94 -0
  81. package/types/Filter.d.ts +324 -0
  82. package/types/FormatContext.d.ts +380 -0
  83. package/types/Frame.d.ts +295 -0
  84. package/types/HWContext.d.ts +62 -0
  85. package/types/Muxer.d.ts +121 -0
  86. package/types/Packet.d.ts +82 -0
  87. package/types/PrivClass.d.ts +25 -0
  88. package/types/Stream.d.ts +165 -0
package/src/packet.h ADDED
@@ -0,0 +1,49 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ #ifndef PACKET_H
23
+ #define PACKET_H
24
+
25
+ #include "node_api.h"
26
+ #include "beamcoder_util.h"
27
+
28
+ extern "C" {
29
+ #include <libavcodec/avcodec.h>
30
+ }
31
+
32
+ void packetFinalizer(napi_env env, void* data, void* hint);
33
+ void packetDataFinalizer(napi_env env, void* data, void* hint);
34
+ void packetBufferFinalizer(napi_env env, void* data, void* hint);
35
+ void packetBufferFree(void* opaque, uint8_t* data);
36
+
37
+ struct packetData {
38
+ AVPacket* packet = nullptr;
39
+ napi_ref dataRef = nullptr;
40
+ int32_t extSize = 0;
41
+ ~packetData() {
42
+ av_packet_free(&packet);
43
+ }
44
+ };
45
+
46
+ napi_value makePacket(napi_env env, napi_callback_info info);
47
+ napi_status fromAVPacket(napi_env env, packetData* packet, napi_value* result);
48
+
49
+ #endif // PACKET_H
@@ -0,0 +1,148 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ const test = require('tape');
23
+ const beamcoder = require('../index.js');
24
+
25
+ test('Creating codec parameters', t => {
26
+ let cps = beamcoder.codecParameters();
27
+ t.ok(cps, 'is truthy.');
28
+ t.equal(cps.name, 'none', 'has no name.');
29
+ t.equal(cps.codec_type, 'data', 'has data type.');
30
+ t.equal(cps.codec_id, 0, 'zero coded id.');
31
+ cps = beamcoder.codecParameters({ name: 'aac' });
32
+ t.equal(cps.name, 'aac', 'has expected name aac.');
33
+ t.equal(cps.codec_type, 'audio', 'has expected type.');
34
+ t.equal(cps.codec_id, 86018, 'zero coded id.');
35
+ cps = beamcoder.codecParameters({ name: 'h264', width: 1920 });
36
+ t.equal(cps.width, 1920, 'constructor parameter set ok.');
37
+ t.end();
38
+ });
39
+
40
+ test('Minimal JSON serialization', t => {
41
+ let cp = beamcoder.codecParameters();
42
+ let cps = JSON.stringify(cp);
43
+ t.equal(typeof cps, 'string', 'stringify creates a string.');
44
+ let cpj = JSON.parse(cps);
45
+ t.deepEqual(cpj, { type: 'CodecParameters', codec_type: 'data',
46
+ codec_id: 0, name: 'none'}, 'is minimal.');
47
+ let rcp = beamcoder.codecParameters(cps);
48
+ t.ok(rcp, 'roundtrip parameters are truthy.');
49
+ t.deepEqual(rcp, { type: 'CodecParameters',
50
+ codec_type: 'data',
51
+ codec_id: 0,
52
+ name: 'none',
53
+ codec_tag: 0,
54
+ extradata: null,
55
+ format: null,
56
+ bit_rate: 0,
57
+ bits_per_coded_sample: 0,
58
+ bits_per_raw_sample: 0,
59
+ profile: -99,
60
+ level: -99,
61
+ width: 0,
62
+ height: 0,
63
+ sample_aspect_ratio: [ 0, 1 ],
64
+ field_order: 'unknown',
65
+ color_range: 'unknown',
66
+ color_primaries: 'unknown',
67
+ color_trc: 'unknown',
68
+ color_space: 'unknown',
69
+ chroma_location: 'unspecified',
70
+ video_delay: 0,
71
+ channel_layout: '0 channels',
72
+ channels: 0,
73
+ sample_rate: 0,
74
+ block_align: 0,
75
+ frame_size: 0,
76
+ initial_padding: 0,
77
+ trailing_padding: 0,
78
+ seek_preroll: 0 }, 'has expected value.');
79
+ t.end();
80
+ });
81
+
82
+ test('Maximal JSON serialization', t=> {
83
+ let cp = beamcoder.codecParameters({
84
+ codec_type: 'video',
85
+ codec_id: 27,
86
+ codec_tag: 'avc1',
87
+ name: 'h264',
88
+ extradata: Buffer.from('wibble'),
89
+ format: 'yuv422p',
90
+ bit_rate: 12345,
91
+ bits_per_coded_sample: 42,
92
+ bits_per_raw_sample: 43,
93
+ profile: 3,
94
+ level: 4,
95
+ width: 44,
96
+ height: 45,
97
+ sample_aspect_ratio: [ 46, 47 ],
98
+ field_order: 'progressive',
99
+ color_range: 'pc',
100
+ color_primaries: 'bt709',
101
+ color_trc: 'bt709',
102
+ color_space: 'bt709',
103
+ chroma_location: 'left',
104
+ video_delay: 48,
105
+ channel_layout: 'stereo',
106
+ channels: 2,
107
+ sample_rate: 48000,
108
+ block_align: 8,
109
+ frame_size: 1920,
110
+ initial_padding: 48,
111
+ trailing_padding: 49,
112
+ seek_preroll: 50 });
113
+ let cps = JSON.stringify(cp);
114
+ t.equal(typeof cps, 'string', 'stringify makes a string.');
115
+ let rcp = beamcoder.codecParameters(cps);
116
+ t.ok(rcp, 'roundtrip value is truthy.');
117
+ t.deepEqual(rcp, { type: 'CodecParameters',
118
+ codec_type: 'video',
119
+ codec_id: 27,
120
+ codec_tag: 'avc1',
121
+ name: 'h264',
122
+ extradata: Buffer.from('wibble'),
123
+ format: 'yuv422p',
124
+ bit_rate: 12345,
125
+ bits_per_coded_sample: 42,
126
+ bits_per_raw_sample: 43,
127
+ profile: 3,
128
+ level: 4,
129
+ width: 44,
130
+ height: 45,
131
+ sample_aspect_ratio: [ 46, 47 ],
132
+ field_order: 'progressive',
133
+ color_range: 'pc',
134
+ color_primaries: 'bt709',
135
+ color_trc: 'bt709',
136
+ color_space: 'bt709',
137
+ chroma_location: 'left',
138
+ video_delay: 48,
139
+ channel_layout: 'stereo',
140
+ channels: 2,
141
+ sample_rate: 48000,
142
+ block_align: 8,
143
+ frame_size: 1920,
144
+ initial_padding: 48,
145
+ trailing_padding: 49,
146
+ seek_preroll: 50 }, 'has expected value.');
147
+ t.end();
148
+ });
@@ -0,0 +1,56 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ const test = require('tape');
23
+ const beamcoder = require('../index.js');
24
+
25
+ test('Creating a decoder', t => {
26
+ let dec = beamcoder.decoder({ name: 'h264' });
27
+ t.ok(dec, 'is truthy.');
28
+ t.equal(dec.name, 'h264', 'has the expected name.');
29
+ t.equal(dec.codec_id, 27, 'has the expected codec_id.');
30
+ t.ok(typeof dec._CodecContext == 'object', 'external value present.');
31
+ t.equal(dec.type, 'decoder', 'has expected type name.');
32
+ t.end();
33
+ });
34
+
35
+ test('Checking the A properties:', t => {
36
+ let dec = beamcoder.decoder({ name: 'h264' });
37
+
38
+ t.deepEqual(dec.active_thread_type, { FRAME: false, SLICE: false},
39
+ 'active_thread_type has expected default.');
40
+ t.throws(() => { dec.active_thread_type = { FRAME: true }; }, /User cannot/,
41
+ 'active_thread_type cannot be set.');
42
+
43
+ t.equals(dec.apply_cropping, 1, 'apply_cropping has exepceted default.');
44
+ t.doesNotThrow(() => { dec.apply_cropping = 0; },
45
+ 'apply_cropping setting does not throw.');
46
+ t.equals(dec.apply_cropping, 0, 'value has been updated.');
47
+
48
+ t.equals(dec.audio_service_type, 'main',
49
+ 'audio_service_type has expected default value.');
50
+ t.throws(() => { dec.audio_service_type = 'dialogue'; },
51
+ /decoding/, 'cannot be updated when deocoding.');
52
+
53
+ t.end();
54
+ });
55
+
56
+ // TODO properties B to Z
@@ -0,0 +1,41 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ const test = require('tape');
23
+ const beamcoder = require('../index.js');
24
+
25
+ test('Creating a demuxer', async t => {
26
+ let dm = await beamcoder.demuxer('https://www.elecard.com/storage/video/bbb_1080p_c.ts');
27
+ t.ok(dm, 'is truthy.');
28
+ t.equal(dm.type, 'demuxer', 'type name says demuxer.');
29
+ t.equal(typeof dm.oformat, 'undefined', 'output format is undefined.');
30
+ t.ok(dm.iformat, 'has an input format.');
31
+ t.equal(dm.iformat.name, 'mpegts', 'input format is mpegts.');
32
+ t.equal(dm.streams.length, 2, 'has 2 streams.');
33
+ try {
34
+ await beamcoder.demuxer('file:jaberwocky.junk');
35
+ t.fail('Did not throw when opening non-existant file.');
36
+ } catch(e) {
37
+ console.log(e.message);
38
+ t.ok(e.message.match(/Problem opening/), 'throws opening non-existant file.');
39
+ }
40
+ t.end();
41
+ });
@@ -0,0 +1,69 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ const test = require('tape');
23
+ const beamcoder = require('../index.js');
24
+
25
+ test('Creating a video encoder', t => {
26
+ let enc = beamcoder.encoder({ name: 'h264' });
27
+ t.ok(enc, 'is truthy.');
28
+ t.equal(enc.name, 'libx264', 'has the expected name.');
29
+ t.equal(enc.codec_id, 27, 'has the expected codec_id.');
30
+ t.ok(typeof enc._CodecContext == 'object', 'external value present.');
31
+ t.equal(enc.type, 'encoder', 'has expected type name.');
32
+ t.end();
33
+ });
34
+
35
+ test('Creating an audio encoder', t => {
36
+ let enc = beamcoder.encoder({ name: 'aac' });
37
+ t.ok(enc, 'is truthy.');
38
+ t.equal(enc.name, 'aac', 'has the expected name.');
39
+ t.equal(enc.codec_id, 86018, 'has the expected codec_id.');
40
+ t.ok(typeof enc._CodecContext == 'object', 'external value present.');
41
+ t.equal(enc.type, 'encoder', 'has expected type name.');
42
+ t.end();
43
+ });
44
+
45
+ test('Checking the A properties:', t => {
46
+ let enc = beamcoder.encoder({ name: 'h264' });
47
+
48
+ t.deepEqual(enc.active_thread_type, { FRAME: false, SLICE: false},
49
+ 'active_thread_type has expected default.');
50
+ t.throws(() => { enc.active_thread_type = { FRAME: true }; }, /User cannot/,
51
+ 'active_thread_type cannot be set.');
52
+
53
+ t.notOk(enc.apply_cropping, 'apply_cropping not defined for encoding.');
54
+ t.throws(() => { enc.apply_cropping = 0; }, /encoding/,
55
+ 'apply_cropping setting does not throw.');
56
+
57
+ t.equals(enc.audio_service_type, 'main',
58
+ 'audio_service_type has expected default value.');
59
+ t.doesNotThrow(() => { enc.audio_service_type = 'dialogue'; },
60
+ 'audio_service_type can be updated.');
61
+ t.equals(enc.audio_service_type, 'dialogue',
62
+ 'audio_service_type has been updated.');
63
+ t.throws(() => { enc.audio_service_type = 'wibble'; },
64
+ 'audio_service_type throws with unknown value.');
65
+
66
+ t.end();
67
+ });
68
+
69
+ // TODO properties B to Z
@@ -0,0 +1,47 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ const test = require('tape');
23
+ const beamcoder = require('../index.js');
24
+
25
+ test('Create a filterer', async t => {
26
+ let flt = await beamcoder.filterer({
27
+ filterType: 'audio',
28
+ inputParams: [
29
+ {
30
+ sampleRate: 48000,
31
+ sampleFormat: 's16',
32
+ channelLayout: 'mono',
33
+ timeBase: [1, 48000]
34
+ }
35
+ ],
36
+ outputParams: [
37
+ {
38
+ sampleRate: 8000,
39
+ sampleFormat: 's16',
40
+ channelLayout: 'mono'
41
+ }
42
+ ],
43
+ filterSpec: 'aresample=8000, aformat=sample_fmts=s16:channel_layouts=mono'
44
+ });
45
+ t.ok(flt, 'is truthy.');
46
+ t.end();
47
+ });