@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/binding.gyp ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "targets": [{
3
+ "target_name" : "beamcoder",
4
+ "sources" : [ "src/beamcoder.cc", "src/beamcoder_util.cc",
5
+ "src/log.cc" ,
6
+ "src/governor.cc", "src/demux.cc",
7
+ "src/decode.cc", "src/filter.cc",
8
+ "src/encode.cc", "src/mux.cc",
9
+ "src/packet.cc", "src/frame.cc",
10
+ "src/codec_par.cc", "src/format.cc",
11
+ "src/codec.cc", "src/hwcontext.cc"],
12
+ "conditions": [
13
+ ['OS!="win"', {
14
+ "defines": [
15
+ "__STDC_CONSTANT_MACROS"
16
+ ],
17
+ "cflags_cc!": [
18
+ "-fno-rtti",
19
+ "-fno-exceptions"
20
+ ],
21
+ "cflags_cc": [
22
+ "-std=c++11",
23
+ "-fexceptions"
24
+ ]
25
+ }],
26
+ ['OS!="win" and OS!="linux"', {
27
+ "link_settings": {
28
+ "libraries": [
29
+ "-lavcodec",
30
+ "-lavdevice",
31
+ "-lavfilter",
32
+ "-lavformat",
33
+ "-lavutil",
34
+ "-lpostproc",
35
+ "-lswresample",
36
+ "-lswscale"
37
+ ]
38
+ }
39
+ }],
40
+ ['OS=="win"', {
41
+ "configurations": {
42
+ "Release": {
43
+ "msvs_settings": {
44
+ "VCCLCompilerTool": {
45
+ "RuntimeTypeInfo": "true"
46
+ }
47
+ }
48
+ }
49
+ },
50
+ "include_dirs" : [
51
+ "ffmpeg/ffmpeg-5.x-win64-shared/include"
52
+ ],
53
+ "libraries": [
54
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/avcodec",
55
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/avdevice",
56
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/avfilter",
57
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/avformat",
58
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/avutil",
59
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/postproc",
60
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/swresample",
61
+ "-l../ffmpeg/ffmpeg-5.x-win64-shared/lib/swscale"
62
+ ],
63
+ "copies": [
64
+ {
65
+ "destination": "build/Release/",
66
+ "files": [
67
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/avcodec-59.dll",
68
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/avdevice-59.dll",
69
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/avfilter-8.dll",
70
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/avformat-59.dll",
71
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/avutil-57.dll",
72
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/postproc-56.dll",
73
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/swresample-4.dll",
74
+ "ffmpeg/ffmpeg-5.x-win64-shared/bin/swscale-6.dll"
75
+ ]
76
+ }
77
+ ]
78
+ }],
79
+ ['OS=="linux"', {
80
+ "libraries": [
81
+ "<!(pkg-config --libs libavcodec)",
82
+ "<!(pkg-config --libs libavdevice)",
83
+ "<!(pkg-config --libs libavfilter)",
84
+ "<!(pkg-config --libs libavformat)",
85
+ "<!(pkg-config --libs libavutil)",
86
+ "<!(pkg-config --libs libpostproc)",
87
+ "<!(pkg-config --libs libswresample)",
88
+ "<!(pkg-config --libs libswscale)"
89
+ ]
90
+ }],
91
+ ['OS=="mac"', {
92
+ "include_dirs" : [
93
+ "/usr/local/Cellar/ffmpeg@5/5.1.3/include/",
94
+ "/opt/homebrew/Cellar/ffmpeg@5/5.1.3/include/",
95
+ ],
96
+ "library_dirs": [
97
+ "/usr/local/Cellar/ffmpeg@5/5.1.3/lib/",
98
+ "/opt/homebrew/Cellar/ffmpeg@5/5.1.3/lib/",
99
+ ]
100
+ }],
101
+ ]
102
+ }]
103
+ }
@@ -0,0 +1,92 @@
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
+ /* Generate a 200 frame test pattern and encode it as a raw H.264 file.
23
+
24
+ Usage: node encode_h264.js <filename.h264>
25
+
26
+ Output can be viewed in VLC. Make sure "All Files" is selected to see the file.
27
+ */
28
+
29
+ const beamcoder = require('../index.js'); // Use require('beamcoder') externally
30
+ const fs = require('fs');
31
+
32
+ let endcode = Buffer.from([0, 0, 1, 0xb7]);
33
+
34
+ async function run() {
35
+ let start = process.hrtime();
36
+ let encParams = {
37
+ name: 'libx264',
38
+ width: 1920,
39
+ height: 1080,
40
+ bit_rate: 2000000,
41
+ time_base: [1, 25],
42
+ framerate: [25, 1],
43
+ gop_size: 10,
44
+ max_b_frames: 1,
45
+ pix_fmt: 'yuv420p',
46
+ priv_data: { preset: 'slow' }
47
+ };
48
+
49
+ let encoder = beamcoder.encoder(encParams);
50
+ console.log('Encoder', encoder);
51
+
52
+ let outFile = fs.createWriteStream(process.argv[2]);
53
+
54
+ for ( let i = 0 ; i < 200 ; i++ ) {
55
+ let frame = beamcoder.frame({
56
+ width: encParams.width,
57
+ height: encParams.height,
58
+ format: encParams.pix_fmt
59
+ }).alloc();
60
+
61
+ let linesize = frame.linesize;
62
+ let [ ydata, bdata, cdata ] = frame.data;
63
+ frame.pts = i;
64
+
65
+ for ( let y = 0 ; y < frame.height ; y++ ) {
66
+ for ( let x = 0 ; x < linesize[0] ; x++ ) {
67
+ ydata[y * linesize[0] + x] = x + y + i * 3;
68
+ }
69
+ }
70
+
71
+ for ( let y = 0 ; y < frame.height / 2 ; y++) {
72
+ for ( let x = 0; x < linesize[1] ; x++) {
73
+ bdata[y * linesize[1] + x] = 128 + y + i * 2;
74
+ cdata[y * linesize[1] + x] = 64 + x + i * 5;
75
+ }
76
+ }
77
+
78
+ let packets = await encoder.encode(frame);
79
+ if ( i % 10 === 0) console.log('Encoding frame', i);
80
+ packets.packets.forEach(x => outFile.write(x.data));
81
+ }
82
+
83
+ let p2 = await encoder.flush();
84
+ console.log('Flushing', p2.packets.length, 'frames.');
85
+ p2.packets.forEach(x => outFile.write(x.data));
86
+ outFile.end(endcode);
87
+
88
+ console.log('Total time ', process.hrtime(start));
89
+ }
90
+
91
+ if (typeof process.argv[2] === 'string') { run(); }
92
+ else { console.error('Error: Please provide a file name.'); }
@@ -0,0 +1,55 @@
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
+ /* Main example from the README.md. Run in a folder of media files.
23
+
24
+ Only supports 8-bit YUV 4:2:2 or 4:2:0 pixel formats.
25
+ */
26
+
27
+ const beamcoder = require('../index.js'); // Use require('beamcoder') externally
28
+ const Koa = require('koa'); // Add koa to package.json dependencies
29
+ const app = new Koa();
30
+
31
+ app.use(async (ctx) => { // Assume HTTP GET with path /<file_name>/<time_in_s>
32
+ let parts = ctx.path.split('/'); // Split the path into filename and time
33
+ if ((parts.length < 3) || (isNaN(+parts[2]))) return; // Ignore favicon etc..
34
+ let dm = await beamcoder.demuxer('file:' + parts[1]); // Probe the file
35
+ await dm.seek({ time: +parts[2] }); // Seek to the closest keyframe to time
36
+ let packet = await dm.read(); // Find the next video packet (assumes stream 0)
37
+ for ( ; packet.stream_index !== 0 ; packet = await dm.read() );
38
+ let dec = beamcoder.decoder({ demuxer: dm, stream_index: 0 }); // Create a decoder
39
+ let decResult = await dec.decode(packet); // Decode the frame
40
+ if (decResult.frames.length === 0) // Frame may be buffered, so flush it out
41
+ decResult = await dec.flush();
42
+ // Filtering could be used to transform the picture here, e.g. scaling
43
+ let enc = beamcoder.encoder({ // Create an encoder for JPEG data
44
+ name : 'mjpeg', // FFmpeg does not have an encoder called 'jpeg'
45
+ width : dec.width,
46
+ height: dec.height,
47
+ pix_fmt: dec.pix_fmt.indexOf('422') >= 0 ? 'yuvj422p' : 'yuvj420p',
48
+ time_base: [1, 1] });
49
+ let jpegResult = await enc.encode(decResult.frames[0]); // Encode the frame
50
+ await enc.flush(); // Tidy the encoder
51
+ ctx.type = 'image/jpeg'; // Set the Content-Type of the data
52
+ ctx.body = jpegResult.packets[0].data; // Return the JPEG image data
53
+ });
54
+
55
+ app.listen(3000); // Start the server on port 3000
@@ -0,0 +1,101 @@
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
+ /* Main example from the README.md with added filtering. Run in a folder of media files.
23
+
24
+ Will convert source pixel formats to 8-bit YUV 4:2:2
25
+ */
26
+
27
+ const beamcoder = require('../index.js'); // Use require('beamcoder') externally
28
+ const Koa = require('koa'); // Add koa to package.json dependencies
29
+ const app = new Koa();
30
+
31
+ app.use(async (ctx) => { // Assume HTTP GET with path /<file_name>/<time_in_s>
32
+ let parts = ctx.path.split('/'); // Split the path into filename and time
33
+ if ((parts.length < 3) || (isNaN(+parts[2]))) return; // Ignore favicon etc..
34
+ let dm = await beamcoder.demuxer('file:' + parts[1]); // Probe the file
35
+ await dm.seek({ time: +parts[2] }); // Seek to the closest keyframe to time
36
+ let packet = await dm.read(); // Find the next video packet (assumes stream 0)
37
+ for ( ; packet.stream_index !== 0 ; packet = await dm.read() );
38
+ let dec = beamcoder.decoder({ demuxer: dm, stream_index: 0 }); // Create a decoder
39
+ let decResult = await dec.decode(packet); // Decode the frame
40
+ if (decResult.frames.length === 0) // Frame may be buffered, so flush it out
41
+ decResult = await dec.flush();
42
+
43
+ // audio test
44
+ const aindex = 2;
45
+ const audStr = dm.streams[aindex];
46
+ // console.log(audStr);
47
+ let adec = beamcoder.decoder({ demuxer: dm, stream_index: aindex }); // Create a decoder
48
+ // console.log(adec);
49
+ let apkt = await dm.read();
50
+ let afrm = await adec.decode(apkt);
51
+ console.log(afrm.frames);
52
+ const audEnc = beamcoder.encoder({
53
+ name: 'aac',
54
+ sample_fmt: 'fltp',
55
+ sample_rate: 48000,
56
+ channels: 1,
57
+ channel_layout: 'mono', });
58
+
59
+ const audFilt = await beamcoder.filterer({ // Create a filterer for audio
60
+ filterType: 'audio',
61
+ inputParams: [{
62
+ sampleRate: audStr.codecpar.sample_rate,
63
+ sampleFormat: adec.sample_fmt,
64
+ channelLayout: audStr.codecpar.channel_layout,
65
+ timeBase: audStr.time_base }],
66
+ outputParams: [{
67
+ sampleRate: 1024,
68
+ sampleFormat: 'fltp',
69
+ channelLayout: 'mono' }],
70
+ filterSpec: 'aresample=1024' });
71
+
72
+ const audFiltPkt = await audFilt.filter([{ frames: afrm }]);
73
+ const encPkt = await audEnc.encode(audFiltPkt[0].frames[0]);
74
+ console.log(encPkt);
75
+
76
+ let vstr = dm.streams[0]; // Select the video stream (assumes stream 0)
77
+ let filt = await beamcoder.filterer({ // Create a filterer for video
78
+ filterType: 'video',
79
+ inputParams: [{
80
+ width: vstr.codecpar.width,
81
+ height: vstr.codecpar.height,
82
+ pixelFormat: vstr.codecpar.format,
83
+ timeBase: vstr.time_base,
84
+ pixelAspect: vstr.sample_aspect_ratio }],
85
+ outputParams: [{ pixelFormat: 'yuv422p' }],
86
+ filterSpec: 'scale=640:360, colorspace=range=jpeg:all=bt709' });
87
+ let filtResult = await filt.filter([{ frames: decResult }]); // Filter the frame
88
+ let filtFrame = filtResult[0].frames[0];
89
+ let enc = beamcoder.encoder({ // Create an encoder for JPEG data
90
+ name : 'mjpeg', // FFmpeg does not have an encoder called 'jpeg'
91
+ width : filtFrame.width,
92
+ height: filtFrame.height,
93
+ pix_fmt: 'yuvj422p',
94
+ time_base: [1, 1] });
95
+ let jpegResult = await enc.encode(filtFrame); // Encode the filtered frame
96
+ await enc.flush(); // Tidy the encoder
97
+ ctx.type = 'image/jpeg'; // Set the Content-Type of the data
98
+ ctx.body = jpegResult.packets[0].data; // Return the JPEG image data
99
+ });
100
+
101
+ app.listen(3000); // Start the server on port 3000
@@ -0,0 +1,123 @@
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
+ /* Generate a 200 frame test pattern and encode it as a raw H.264 file.
23
+
24
+ Usage: node encode_h264.js <filename.h264>
25
+
26
+ Output can be viewed in VLC. Make sure "All Files" is selected to see the file.
27
+ */
28
+
29
+ const beamcoder = require('../index.js'); // Use require('beamcoder') externally
30
+ const fs = require('fs');
31
+
32
+ let endcode = Buffer.from([0, 0, 1, 0xb7]);
33
+
34
+ async function run() {
35
+ let start = process.hrtime();
36
+ let encParams = {
37
+ name: 'libx264',
38
+ width: 1920,
39
+ height: 1080,
40
+ bit_rate: 2000000,
41
+ time_base: [1, 25],
42
+ framerate: [25, 1],
43
+ gop_size: 10,
44
+ max_b_frames: 1,
45
+ pix_fmt: 'yuv420p',
46
+ priv_data: { preset: 'slow' }
47
+ };
48
+
49
+ let encoder = await beamcoder.encoder(encParams);
50
+ console.log('Encoder', encoder);
51
+
52
+ const mux = beamcoder.muxer({ format_name: 'mp4' });
53
+ let vstr = mux.newStream({
54
+ name: 'h264',
55
+ time_base: [1, 90000],
56
+ interleaved: true }); // Set to false for manual interleaving, true for automatic
57
+ Object.assign(vstr.codecpar, {
58
+ width: 1920,
59
+ height: 1080,
60
+ format: 'yuv420p'
61
+ });
62
+ console.log(vstr);
63
+ await mux.openIO({
64
+ url: 'file:test.mp4'
65
+ });
66
+ await mux.writeHeader();
67
+
68
+ let outFile = fs.createWriteStream(process.argv[2]);
69
+
70
+ for ( let i = 0 ; i < 200 ; i++ ) {
71
+ let frame = beamcoder.frame({
72
+ width: encParams.width,
73
+ height: encParams.height,
74
+ format: encParams.pix_fmt
75
+ }).alloc();
76
+
77
+ let linesize = frame.linesize;
78
+ let [ ydata, bdata, cdata ] = frame.data;
79
+ frame.pts = i+100;
80
+
81
+ for ( let y = 0 ; y < frame.height ; y++ ) {
82
+ for ( let x = 0 ; x < linesize[0] ; x++ ) {
83
+ ydata[y * linesize[0] + x] = x + y + i * 3;
84
+ }
85
+ }
86
+
87
+ for ( let y = 0 ; y < frame.height / 2 ; y++) {
88
+ for ( let x = 0; x < linesize[1] ; x++) {
89
+ bdata[y * linesize[1] + x] = 128 + y + i * 2;
90
+ cdata[y * linesize[1] + x] = 64 + x + i * 5;
91
+ }
92
+ }
93
+
94
+ let packets = await encoder.encode(frame);
95
+ if ( i % 10 === 0) console.log('Encoding frame', i);
96
+ for (const pkt of packets.packets) {
97
+ pkt.duration = 1;
98
+ pkt.stream_index = vstr.index;
99
+ pkt.pts = pkt.pts * 90000/25;
100
+ pkt.dts = pkt.dts * 90000/25;
101
+ await mux.writeFrame(pkt);
102
+ outFile.write(pkt.data);
103
+ }
104
+ }
105
+
106
+ let p2 = await encoder.flush();
107
+ console.log('Flushing', p2.packets.length, 'frames.');
108
+ for (const pkt of p2.packets) {
109
+ pkt.duration = 1;
110
+ pkt.stream_index = vstr.index;
111
+ pkt.pts = pkt.pts * 90000/25;
112
+ pkt.dts = pkt.dts * 90000/25;
113
+ await mux.writeFrame(pkt);
114
+ outFile.write(pkt.data);
115
+ }
116
+ await mux.writeTrailer();
117
+ outFile.end(endcode);
118
+
119
+ console.log('Total time ', process.hrtime(start));
120
+ }
121
+
122
+ if (typeof process.argv[2] === 'string') { run(); }
123
+ else { console.error('Error: Please provide a file name.'); }
Binary file
package/index.d.ts ADDED
@@ -0,0 +1,83 @@
1
+ export * from "./types/CodecPar"
2
+ export * from "./types/Packet"
3
+ export * from "./types/Frame"
4
+ export * from "./types/Stream"
5
+ export * from "./types/Codec"
6
+ export * from "./types/FormatContext"
7
+ export * from "./types/Demuxer"
8
+ export * from "./types/Decoder"
9
+ export * from "./types/Filter"
10
+ export * from "./types/Encoder"
11
+ export * from "./types/Muxer"
12
+ export * from "./types/Beamstreams"
13
+ export * from "./types/HWContext"
14
+
15
+ export const AV_NOPTS_VALUE: number
16
+
17
+ /** The LIBAV**_VERSION_INT for each FFmpeg library */
18
+ export function versions(): {
19
+ avcodec: number
20
+ avdevice: number
21
+ avfilter: number
22
+ avformat: number
23
+ avutil: number
24
+ postproc: number
25
+ swresample: number
26
+ swscale: number
27
+ }
28
+ /**
29
+ * FFmpeg version string. This usually is the actual release
30
+ * version number or a git commit description. This string has no fixed format
31
+ * and can change any time. It should never be parsed by code.
32
+ */
33
+ export function avVersionInfo(): string
34
+ /** Informative version strings for each FFmpeg library */
35
+ export function versionStrings(): {
36
+ avcodec: string
37
+ avdevice: string
38
+ avfilter: string
39
+ avformat: string
40
+ avutil: string
41
+ postproc: string
42
+ swresample: string
43
+ swscale: string
44
+ }
45
+ /** Build configuration strings for each FFmpeg library */
46
+ export function configurations(): {
47
+ avcodec: string
48
+ avdevice: string
49
+ avfilter: string
50
+ avformat: string
51
+ avutil: string
52
+ postproc: string
53
+ swresample: string
54
+ swscale: string
55
+ }
56
+ /** License strings for each FFmpeg library */
57
+ export function licenses(): {
58
+ avcodec: string
59
+ avdevice: string
60
+ avfilter: string
61
+ avformat: string
62
+ avutil: string
63
+ postproc: string
64
+ swresample: string
65
+ swscale: string
66
+ }
67
+ /** List the available protocols */
68
+ export function protocols(): { inputs: Array<string>, outputs: Array<string> }
69
+
70
+ /** Read or set the logging level
71
+ * `quiet` - print no output.
72
+ * `panic` - something went really wrong - crash will follow
73
+ * `fatal` - recovery not possible
74
+ * `error` - lossless recovery not possible
75
+ * `warning` - something doesn't look correct
76
+ * `info` - standard information - the default
77
+ * `verbose` - detailed information
78
+ * `debug` - stuff which is only useful for libav* developers
79
+ * `trace` - extremely verbose debugging for libav* developers
80
+ */
81
+ export function logging(level?: string): string | undefined
82
+
83
+ export as namespace Beamcoder
package/index.js ADDED
@@ -0,0 +1,44 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings to 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 beamcoder = require('bindings')('beamcoder');
23
+ const beamstreams = require('./beamstreams.js');
24
+
25
+ // Provide useful debug on segfault-related crash
26
+ const SegfaultHandler = require('segfault-handler');
27
+ SegfaultHandler.registerHandler('crash.log');
28
+
29
+ const splash = `Aerostat Beam Coder Copyright (C) 2019 Streampunk Media Ltd
30
+ GPL v3.0 or later license. This program comes with ABSOLUTELY NO WARRANTY.
31
+ This is free software, and you are welcome to redistribute it
32
+ under certain conditions. Conditions and warranty at:
33
+ https://github.com/Streampunk/beamcoder/blob/master/LICENSE`;
34
+
35
+ console.log(splash);
36
+ console.log('Using FFmpeg version', beamcoder.avVersionInfo());
37
+
38
+ beamcoder.demuxerStream = beamstreams.demuxerStream;
39
+ beamcoder.muxerStream = beamstreams.muxerStream;
40
+
41
+ beamcoder.makeSources = beamstreams.makeSources;
42
+ beamcoder.makeStreams = beamstreams.makeStreams;
43
+
44
+ module.exports = beamcoder;