Giter Club home page Giter Club logo

node-gstreamer-superficial's People

Contributors

chfritz avatar chromakode avatar dfischer23 avatar dturing avatar linux4kix avatar lleon95 avatar macdudeuk avatar maruware avatar skaughtx0r avatar skyrising avatar zubnix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-gstreamer-superficial's Issues

Cannot run in multiple worker theads

Is this package context aware?
It does run in node worker threads, but only a single thread.

I have an appsink in my pipeline, if I run 2 or more threads it will segfault during init:

Thread 1: pipeline.findChild('sink')
Result: OK

Thread 2: pipeline.findChild('sink')
Result: FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope

unable to find gst/gst.h

Not sure if its just the version of gstreamer I have installed in windows or not but the environment variable on my windows 10 and fresh install of gstreamer is GSTREAMER_1_0_ROOT_MSVC_X86_64=C:\gstreamer\1.0\msvc_x86_64\

I had to duplicate it for GSTREAMER_1_0_ROOT_X86_64=C:\gstreamer\1.0\msvc_x86_64\ inorder to get npm to install gstreamer-superficial.

Write message to bus

Hi guys. If anyone feels like tackling it, it would be great to have a way to send a message to the GStreamer bus. In particular sending EOS before tearing down a pipeline.In fact a way to cleanly close a pipeline in general. If you are recording anything to a file this is pretty much mandatory and would make this module useful in more situations. Sadly such an enhancement is past my capabilities...

PS Love it so far.

Cannot set int/enum type property using the object wrapper setter

I was unable to set any "mode" kinda value on pad since "v8_to_gvalue" cast any number type to gfloat. Forking and add the below code solves my issue, is there a better way of doing this?

if (v->IsNumber()) { auto number = v->ToNumber(Nan::GetCurrentContext()).ToLocalChecked(); if (number->IsInt32()) { g_value_init(gv, G_TYPE_INT); g_value_set_int(gv, number->ToInteger(Nan::GetCurrentContext()).ToLocalChecked()->Value()); } else { g_value_init(gv, G_TYPE_FLOAT); g_value_set_float(gv, number->Value()); } }

Doest not work on raspberry pi and amazon kinesis

I try to run gstreamer superficial on rpi and kinesis video and show this. But same code works fine on macbook pro.
### This is my code

const gstreamer = require('gstreamer-superficial');

const pipeline = new gstreamer.Pipeline(`videotestsrc is-live=true ! \

video/x-raw,framerate=25/1 ! \

videoconvert ! \

x264enc bframes=0 key-int-max=30 bitrate=300 tune=stillimage  ! \

h264parse ! \

video/x-h264,stream-format=avc,alignment=au,profile=baseline ! \

kvssink stream-name=stream1_in storage-size=128 \

access-key="-----------" secret-key="---------"`

);

pipeline.play();
pipeline.pollBus(msg => {
       console.log('pipeline.pollBus', msg);

});

THE ERROR:

INFO - createKinesisVideoClient(): Creating Kinesis Video Client 2020-01-12 17:37:09 [1995569920] INFO - heapInitialize(): Initializing native heap with limit size 134217728, spill ratio 0% and flags 0x00000001 2020-01-12 17:37:09 [1995569920] INFO - heapInitialize(): Creating AIV heap. 2020-01-12 17:37:09 [1995569920] INFO - heapInitialize(): Heap is initialized OK 2020-01-12 17:37:09 [1995569920] DEBUG - stepStateMachine(): State Machine - Current state: 0x0000000000000001, Next state: 0x0000000000000002 2020-01-12 17:37:09 [1995569920] DEBUG - getSecurityTokenHandler invoked 2020-01-12 17:37:09 [1995569920] DEBUG - Refreshing credentials. Force refreshing: 0 Now time is: 1578861429428906712 Expiration: 0 2020-01-12 17:37:09 [1995569920] DEBUG - stepStateMachine(): State Machine - Current state: 0x0000000000000002, Next state: 0x0000000000000010 2020-01-12 17:37:09 [1995569920] INFO - createDeviceResultEvent(): Create device result event. 2020-01-12 17:37:09 [1995569920] DEBUG - stepStateMachine(): State Machine - Current state: 0x0000000000000010, Next state: 0x0000000000000040 2020-01-12 17:37:09 [1995569920] DEBUG - clientReadyHandler invoked 2020-01-12 17:37:09 [1995569920] INFO - try creating stream 2020-01-12 17:37:09 [1995569920] INFO - Creating Kinesis Video Stream stream2_in 2020-01-12 17:37:09 [1995569920] INFO - createKinesisVideoStream(): Creating Kinesis Video Stream. 2020-01-12 17:37:09 [1995569920] DEBUG - stepStateMachine(): State Machine - Current state: 0x0000000000000001, Next state: 0x0000000000000002 2020-01-12 17:37:09 [1995569920] Violación de segmento

Do you know about this issue? or what can I do

Feature request: Pushing data to GStreamer

Do you think it will be possible to push data from NodeJS into Gstreamer? Within Gstreamer there's an element named "appsrc" which allows applications to push data (buffers) into GStreamer. I was thinking something along the line of:

pipeline.push([buffer]);

gstreamer-superficial blocks libuv workers

We had an issue when using many instances of gstreamer-superficial (e.g. new gstreamer.Pipeline) on a single Node.js instance, where dns and fs appear to stop working and never recover. I am sharing this as the problem was confusing and hard to track down. We use multiple gstreamer-superficial instances for the purposes of recording many incoming WebRTC streams.

TL;DR

As long as you set the environment variable UV_THREADPOOL_SIZE greater than the number of concurrent gstreamer-superficial pipelines, you'll have normal stable performance.

Explanation

(please correct me if this is not correct)

gstreamer-superficial uses nan AsyncWorker which consumes a thread in the libuv thread pool, so when you create many of them, they exhaust the thread pool leading to:

  • Can't make dns lib requests - they never get sent to the network interface
  • Can't make fs lib calls - nothing happens

The thread blocking may be related/limited to the use of pipeline.pollBus (unconfirmed). Anyway, as default UV_THREADPOOL_SIZE=4 so if you're going to expect 50 pipelines concurrently, set something like UV_THREADPOOL_SIZE=64 and you'll be fine. As stated here, the max value for newer Node.js versions is 1024 and the it uses approx. "~1MB for 128 threads", so it's a nice fix with little other impact. 👍

pipeline not start

hello
can you explain how enable gst_debug for watch log ?
I want implement this example https://gstreamer.freedesktop.org/documentation/opengl/glshader.html?gi-language=javascript

However, my pipeline no work

bellow my test code :

#!/usr/bin/env node

const gstreamer = require('../..');
const { exec } = require('child_process');

function execPromise(command) {
return new Promise(function(resolve, reject) {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
resolve(stdout.trim());
});
});
}

async function set_shader(obj)
{

try {
var result = await execPromise('cat myshader.frag');
console.log(result);
var test = typeof 'result';
//console.log('arg',test);
console.log(obj)
obj['fragment'] = result;
console.log(obj)

    return result;

} catch (e) {
console.error(e.message);
}
}

const pipeline = new gstreamer.Pipeline('videotestsrc ! glupload ! glshader name=glshader ! glimagesink' )

pipeline.play();
if( pipeline != 0)
{
console.log(' start pipeline');
}

const glshader = pipeline.findChild('glshader')
if(glshader != 0)
{
set_shader(glshader);
}
else
{
console.log('gltransformation isn t available ');
}

build error (0.10.29 | darwin | x64)

Hi Daniel, nice work!

But I get a strange build error. I can't figure out why v8::ArrayBuffer should be a problem, but I'm not a Node / C++ expert.


node-gyp build
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | darwin | x64
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
CXX(target) Release/obj.target/gstreamer-superficial/gstreamer.o
../gstreamer.cc:12:47: error: no member named 'ArrayBuffer' in namespace 'v8'
class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
~~~~^
../gstreamer.cc:12:60: error: expected class name
class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
^
../gstreamer.cc:586:4: error: no member named 'SetArrayBufferAllocator' in 'v8::V8'; did you mean 'MallocArrayBufferAllocator'?
v8::V8::SetArrayBufferAllocator(new MallocArrayBufferAllocator());
^~~~~~~~
../gstreamer.cc:12:7: note: 'MallocArrayBufferAllocator' declared here
class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
^
3 errors generated.
make: *** [Release/obj.target/gstreamer-superficial/gstreamer.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: make failed with exit code: 2


appsrc example errors

i just run node examples/appsrc.js , have following errors

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.714: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.752: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.787: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.824: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.858: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.899: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.933: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:52.965: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:53.005: gst_segment_to_stream_time: assertion 'segment->format == format' failed

(<unknown>:67082): GStreamer-CRITICAL **: 21:33:53.039: gst_segment_to_stream_time: assertion 'segment->format == format' failed

i am running this on macos with node v8.11.1

runtime problem

module.js:598

return process.dlopen(module, path._makeLong(filename));
^

Error: /home/aokihu/gst-test/node_modules/gstreamer-superficial/build/Release/gstreamer-superficial.node: undefined symbol: _ZN8Pipeline10GetLatencyEN2v85LocalINS0_6StringEEERKN3Nan20PropertyCallbackInfoINS0_5ValueEEE

new problem, why?

After upgrading to GStreamer 1.16.0 -> I get an undefined symbol error

After the gstreamer upgrade my node app won't launch anymore and I get:

internal/modules/cjs/loader.js:730
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: /app/ctrl/node_modules/gstreamer-superficial/build/Release/gstreamer-superficial.node: undefined symbol: _ZN2v86Object11SetAccessorENS_5LocalINS_7ContextEEENS1_INS_4NameEEEPFvS5E
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:730:18)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/app/ctrl/ctrl.min.js:1:79)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)

Install fails, can'æt find gstreamer-1.0.pc

When I attempt npm install -g gstreamer-superficial, I get this error:


> [email protected] install /usr/lib/node_modules/gstreamer-superficial
> node-gyp rebuild

Package gstreamer-1.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gstreamer-1.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gstreamer-1.0' found
gyp: Call to 'pkg-config gstreamer-1.0 --libs' returned exit status 1 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:336:16)
gyp ERR! stack     at emitTwo (events.js:125:13)
gyp ERR! stack     at ChildProcess.emit (events.js:213:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Linux 4.9.24-v7+
gyp ERR! command "/usr/bin/nodejs" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /usr/lib/node_modules/gstreamer-superficial
gyp ERR! node -v v8.3.0
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2017-09-21T22_33_32_975Z-debug.log

I do have gstreamer-1.0 installed (I've even used it), but as the whole cluster of gstreamer packages on Debian seem to be a huge mess, I might be on the wrong package.

Do you have any installation instructions?

I directly transplant the module from one computer to other computer, but it not work

I move the project from computer A to computer B, and don't rebuild getreamer-superficial, I think it will work well as other node modules, but it is not

Two computer are all ARM arch, and chip is small

  return process.dlopen(module, path._makeLong(filename));
                 ^

Error: File not found
    at Error (native)
    at Object.Module._extensions..node (module.js:597:18)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/root/gst-test/test.js:1:81)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)```

Node 12 support

It seems npm install fails on node 12 (12.12.0). Handle is not defined.

> node-gyp rebuild

make: Entering directory '/home/manuel/playground/node_modules/gstreamer-superficial/build'
  CXX(target) Release/obj.target/gstreamer-superficial/gstreamer.o
In file included from ../gstreamer.cpp:4:0:
../GLibHelpers.h:9:1: error: ‘Handle’ does not name a type; did you mean ‘rand_r’?
 Handle<Object> createBuffer(char *data, int length);
 ^~~~~~
 rand_r
../GLibHelpers.h:11:1: error: ‘Handle’ does not name a type; did you mean ‘rand_r’?
 Handle<Value> gstsample_to_v8( GstSample *sample );
 ^~~~~~
 rand_r
../GLibHelpers.h:12:1: error: ‘Handle’ does not name a type; did you mean ‘rand_r’?
 Handle<Value> gstvaluearray_to_v8( const GValue *gv );
 ^~~~~~
 rand_r
../GLibHelpers.h:13:1: error: ‘Handle’ does not name a type; did you mean ‘rand_r’?
 Handle<Value> gvalue_to_v8( const GValue *gv );

Is there already a workaround?

node-gstreamer-superficial crashes nodejs process

It looks like node-gstreamer-superficial crashes sometimes, which seems to be killing the entire nodejs process.

It may be crashing due to gstreamer bug. If yes, I am hoping that node-gstreamer-superficial can handle it gracefully without killing the entire nodejs process.

visual studio problem

I received this error what's the problem ?:

D:\Develope\examples\node-gstreamer-superficial>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\....\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js"rebuild )
gyp ERR! UNCAUGHT EXCEPTION
gyp ERR! stack Error: spawn C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\15.0\Bin\MSBuild.exe ENOENT
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
gyp ERR! stack at onErrorNT (internal/child_process.js:415:16)
gyp ERR! stack at process._tickCallback (internal/process/next_tick.js:63:19)
gyp ERR! System Windows_NT 10.0.17763
gyp ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd D:\Develope\examples\node-gstreamer-superficial
gyp ERR! node -v v10.15.2
gyp ERR! node-gyp -v v3.8.0
gyp ERR! This is a bug in node-gyp.
gyp ERR! Try to update node-gyp and file an Issue if it does not help:
gyp ERR! https://github.com/nodejs/node-gyp/issues
npm ERR! code ELIFECYCLE
npm ERR! errno 7
npm ERR! [email protected] install: node-gyp rebuild
npm ERR! Exit status 7
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\SMH\AppData\Roaming\npm-cache_logs\2019-08-10T06_46_09_207Z-debug.log

Example for receiving current Position

Hi!
Thanks for your great work!

Could you PLZ give an example, of how to receive the current play position?

pipeline.query_position(gst.FORMAT_TIME)

THANKS for advice

Getting examples/streaming/server.js to work?

Any ideas on how to get examples/streaming/server.js to work? You acknowledge on the main page that it's broken. I want to try to stream the appsink to multiple clients like you did in this example. I want to do it from MP4 streams or similar to what mpeg-streamer does. I got this example to work but it's seems only compatible with one client.

I got it to run after express-logger is installed npm install express-logger --save . I changed the app.use on line 39 to app.use( logger({path: "logfile.txt"})); just to get it to run.

The main issue seems to be appsink.pull(function (buf) {..} is only being called one time. Shouldn't it be called continuously after the stream is put into play? This is what happens the appsink.js examples.

The second issues is the appsink.pull function(caps) {..} is never called. I like what you were trying to do here so I guess this just means lines 43-45 aren't used.

I uncommitted lines 13 and 23 and get the output below when I run server.js. The only one display of BUFFER size 70 indicates just one invoke of the callback.

I played with adding is-live=true and drop=true to the pipeline. That didn't fix it. I can try other ideas on debugging.

--Server Output--
Running http server on port 8001
bus message: { type: 'state-changed' }
BUFFER size 70
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'stream-status' }
bus message: { type: 'state-changed' }
bus message: { type: 'stream-status' }
bus message: { type: 'stream-start' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'async-done' }
bus message: { type: 'new-clock' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }
bus message: { type: 'state-changed' }

AppSink hangs and blocks the requests (gstreamer-superficial)

Hi all,

I am using gstreamer-superficial library for live-streaming. My NodeJs server starts a websocket server which receives requests from multiple websocket clients.
Each websocket client request is per camera. Based on some validations, I start the pipeline on first "start" request and use the same pipeline for different websocket client "start" requests on same camera and I will call pipeline.stop() on last "stop" request. Everything is working fine.

But I see some problems here:

  1. I am printing appsink element on every request and seeing parent property which increases pipeline number (example: parent: '(GstPipeline) pipeline4') on every request. After stopping the pipeline (pipeline.stop()), what happens to that pipeline?

is it actually unreferred? If yes, why the pipeline count is keep on increasing? If I restart my node server, again the count starts from 0

GstAppSink {
name: 'sink',
parent: '(GstPipeline) pipeline4',
sync: true,
'max-lateness': '-1',
qos: false,
async: true,
'ts-offset': '0',
'enable-last-sample': true,
'last-sample': { buf: null, caps: {} },
blocksize: 4096,
'render-delay': '0',
'throttle-time': '0',
'max-bitrate': '0',
caps: 'NULL',
eos: false,
'emit-signals': false,
'max-buffers': 1,
drop: true,
'wait-on-eos': true,
pull: [Function: pull]
}

Note: On pipeline.stop(), only gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); is called. Should we also consider calling something like gst_element_unref() ? just a thought !!

  1. This is my pipeline :
    pipeline = new gstreamer.Pipeline(rtmpsrc location=rtmp://localhost:3030/show/111 ! decodebin ! jpegenc quality=30 ! appsink max-buffers=1 drop=TRUE name=sink);

After watching live-stream for sometime, my node websocket server hangs up. And all the requests which are coming to my websocket server are blocked, none of them proceeds to execute. I have to restart my node server in order to proceed. Since we are using many cameras for surveillance, this becomes blocker. Please help me to solve this

  1. On invoking pipeline.stop() method, I am seeing pipeline new state changed to GST_STATE_PAUSED. it should be GST_STATE_NULL, right? Could you please test once and confirm this.

I apologize for too many questions. Since this has become the blocker, any help would be grateful.

webrtcbin usage [feature request]

First, thanks for creating this NodeJS bindings for GStreamer.
Lately, I've discovered the rather new webrtcbin element and wondered what we need to add to gstreamer-superficial to make it usable here.

For reference, here's a python sample code (simpler to understand) that shows interactions with this webrtcbin element:
https://gitlab.freedesktop.org/gstreamer/gst-examples/-/blob/master/webrtc/sendrecv/gst/webrtc_sendrecv.py#L129

In particular how could we modify the cpp wrapper files used by gstreamer-superficial to add these:

GstSdp.SDPMessage.new
GstSdp.sdp_message_parse_buffer
GstWebRTC.WebRTCSessionDescription.new
Gst.Promise.new

And also can we emit things to the webrtc element, like done in
https://gitlab.freedesktop.org/gstreamer/gst-examples/-/blob/master/webrtc/sendrecv/gst/webrtc_sendrecv.py#L133

I'm aware this would make it less superficial ;)

How does one use the `autovideosink`?

Hello, I am new to this library (and also pretty new to Gstreamer).

I am testing the examples to get a grasp, and thus far I noticed that it only works with node v12.11…

There the code runs seemingly without error, however, also without output?

I have tested gst-launch-1.0 videotestsrc ! autovideosink and a little window opens up to show me that videotestsrc however, if I do the same little piece of code with node-gstreamer-superficial, I don't get a window at all?

Any help would be appreciated.

P.S.: I am on macOS with node version 12.11.1 active for the testing.

featurerequest

It would be great to have the following functions built in superficial:

.) list all open gstreamer pipelines
.) close/kill a pipeline (by name)

Many thanks for all your work and time you spent in this projekt. Its great!

Node-gyp rebuild fails on npm install - gstappsink.h No such file or directory

Versions

Node v12.22.6
Npm 6.14.15
Raspbian 11 Bullseye on Raspberry Pi 4b

Gstreamer packages installed
$ apt list --installed | grep gst

gir1.2-gstreamer-1.0/stable,now 1.18.4-2.1 armhf [installed,automatic]
gstreamer1.0-alsa/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-gl/stable,now 1.18.4-2 armhf [installed,automatic]
gstreamer1.0-libav/stable,now 1.18.4-3 armhf [installed]
gstreamer1.0-omx-generic-config/stable,now 1.18.3-1 armhf [installed]
gstreamer1.0-omx-generic/stable,now 1.18.3-1 armhf [installed,automatic]
gstreamer1.0-opencv/stable,now 1.18.4-3 armhf [installed]
gstreamer1.0-plugins-bad/stable,now 1.18.4-3 armhf [installed]
gstreamer1.0-plugins-base-apps/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-plugins-base/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-plugins-good/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-plugins-ugly/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-rtsp/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-tools/stable,now 1.18.4-2.1 armhf [installed,automatic]
gstreamer1.0-vaapi/stable,now 1.18.4-2 armhf [installed]
gstreamer1.0-wpe/stable,now 1.18.4-3 armhf [installed]
gstreamer1.0-x/stable,now 1.18.4-2 armhf [installed,automatic]
libgstreamer-gl1.0-0/stable,now 1.18.4-2 armhf [installed,automatic]
libgstreamer-opencv1.0-0/stable,now 1.18.4-3 armhf [installed,automatic]
libgstreamer-plugins-bad1.0-0/stable,now 1.18.4-3 armhf [installed,automatic]
libgstreamer-plugins-base1.0-0/stable,now 1.18.4-2 armhf [installed,automatic]
libgstreamer1.0-0/stable,now 1.18.4-2.1 armhf [installed,automatic]
libgstreamer1.0-dev/stable,now 1.18.4-2.1 armhf [installed]
libgstrtspserver-1.0-0/stable,now 1.18.4-2 armhf [installed,automatic]

The problem

Hi, I'm getting a node-gyp compile error when I run npm install in the root of the master branch. I first encountered the problem in #22, but quickly resolved by installing package libgstreamer1.0-dev.
Now I am seeing ../GObjectWrap.cpp:3:10: fatal error: gst/app/gstappsink.h: No such file or directory. Here is the full output:

$ npm install

> [email protected] install /home/broadcaster/node-gstreamer-superficial
> node-gyp rebuild

make: Entering directory '/home/broadcaster/node-gstreamer-superficial/build'
  CXX(target) Release/obj.target/gstreamer-superficial/gstreamer.o
  CXX(target) Release/obj.target/gstreamer-superficial/GLibHelpers.o
  CXX(target) Release/obj.target/gstreamer-superficial/GObjectWrap.o
../GObjectWrap.cpp:3:10: fatal error: gst/app/gstappsink.h: No such file or directory
    3 | #include <gst/app/gstappsink.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [gstreamer-superficial.target.mk:122: Release/obj.target/gstreamer-superficial/GObjectWrap.o] Error 1
make: Leaving directory '/home/broadcaster/node-gstreamer-superficial/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/broadcaster/.nvm/versions/node/v12.22.6/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:314:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)
gyp ERR! System Linux 5.10.52-v7l+
gyp ERR! command "/home/broadcaster/.nvm/versions/node/v12.22.6/bin/node" "/home/broadcaster/.nvm/versions/node/v12.22.6/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/broadcaster/node-gstreamer-superficial
gyp ERR! node -v v12.22.6
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok 
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/broadcaster/.npm/_logs/2021-09-12T21_41_46_618Z-debug.log

As you can see in the Gstreamer package versions above, I have Gstreamer 1.18 installed. Any ideas what this error is caused by?

gstreamer missing elements when built for NWJS

When addon is used with pure nodejs, all works totally fine, but when it is compiled for nwjs, then i'm receiving errors of missing gstreamer elements, like avdec_h264. GstError: no element "avdec_h264"
It looks like under nwjs environment gstreamer-superficial is not using a gst, which is already installed on system, but it tries to use another kind.

Later i have added ffmpeg to my nwjs and received different error:
Crashing due to FD ownership violation

nwjs 0.69.1
ubuntu 22

Newer versions of Node.js show `illegal hardware instructions` error

Hello, as mentioned in the other issue, I am new to Gstreamer and this package.

At first I tried installing this package on node version 12.14.1 and wonderred why it would through the

[1]    18705 illegal hardware instruction  ./test.js

error message. Then I found that this is currently only compatible up until 12.11.

Maybe this issue can be a path to upgrading the package to be compatible with the newest LTS version v12.16?

Thanks, Chris.

Memory Leak

Hi

I am getting a consistent memory leak when pulling data from appsink. This is true using the example apps too. For instance if you run appsink.js with the following pipeline:

videotestsrc is-live=true ! appsink max-buffers=1 drop=true name=sink

Then it quickly eats all available memory.

Using node inspector, the leak does not seem to be in the node.js environment, and checking the code in GObjectWrap.cpp there is a call to gst_sample_unref() so I am confused where it is leaking.

Any help appreciated.

Add TypeScript definitions

Add TypeScript definitions for this module

I'm starting this, and will make a MR when ready; just filing the issue to track it

ERR_DLOPEN_FAILED after successful npm -i

Trying to run the m-jpeg-streamer after a successful build / install (I was fighting with #46 for a while), I'm now getting this error:

 node .\server.js
node:internal/modules/cjs/loader:1189
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The specified module could not be found.

Platform:
Windows 10
Node v16.15.1

install fails on arm(beaglebone black) Debian GNU/Linux 8

installing with the bellow command fails on the beaglebone black. I'm suspecting it's from an unlisted dependency.

bash dump:
root@bone:/var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial# npm install @skyrising/gstreamer-superficial --save

@skyrising/[email protected] install /var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial/node_modules/@skyrising/gstreamer-superficial
node-gyp rebuild

module.js:338
throw err;
^
Error: Cannot find module 'nan'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at [eval]:1:1
at Object.exports.runInThisContext (vm.js:74:17)
at Object. ([eval]-wrapper:6:22)
at Module._compile (module.js:460:26)
at evalScript (node.js:431:25)
at startup (node.js:90:7)
gyp: Call to 'node -e "require('nan')"' returned exit status 1 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: gyp failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:305:16)
gyp ERR! stack at ChildProcess.emit (events.js:110:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:1078:12)
gyp ERR! System Linux 4.4.9-ti-r25
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial/node_modules/@skyrising/gstreamer-superficial
gyp ERR! node -v v0.12.17
gyp ERR! node-gyp -v v3.3.1
gyp ERR! not ok
npm WARN [email protected] No license field.
npm ERR! Linux 4.4.9-ti-r25
npm ERR! argv "node" "/usr/local/bin/npm" "install" "@skyrising/gstreamer-superficial" "--save"
npm ERR! node v0.12.17
npm ERR! npm v3.8.2
npm ERR! code ELIFECYCLE

npm ERR! @skyrising/[email protected] install: node-gyp rebuild
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @skyrising/[email protected] install script 'node-gyp rebuild'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @skyrising/gstreamer-superficial package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-gyp rebuild
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs @skyrising/gstreamer-superficial
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls @skyrising/gstreamer-superficial
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial/npm-debug.log

npm-debug.log.txt

require('gstreamer-superficial') hangs

This evening I tried to get your node module to work because I was looking for a way to "interact" with gstreamer. And nodejs is currently my language of choice... The module compiled fine once I had the developer version of Gstreamer in place and made sure that PKG_CONFIG_PATH was pointing to the correct dir. (For some reason I couldn't get it to install globally using 'npm install -g' but that's not my main concern right now)

Next stop was to run an example. Once I issued the command to run an example no errors pop up. It just doesn't do anything. That's when I started the example app using node-debug. The step-debugger learned me that once it hits the

require('..');

line it "hangs". The debugger doesn't hit the next line. It seems that it takes forever to load the gstreamer-superficial module. What could be wrong?

Note that I'm running Gstreamer 1.10.2 on OSX with node v4.6.0.

pipeline working in node.js or console, but fails in nw.js

I'm struggling with the following, simple pipeline:

const pipeline = new gstreamer.Pipeline('filesrc location=/home/rpi/Downloads/Off-Lazarov.mp4 ! decodebin ! autovideosink');

uring this line in node.js works fine. But The same line used within nw.js ( process.versions['node-webkit'] == 0.41.3 ) returns:

[4758:4758:0814/115547.642413:ERROR:CONSOLE(5192)] "Cannot find context with specified id", source: devtools://devtools/bundled/shell.js (5192)
[4758:4758:0814/115547.642636:ERROR:CONSOLE(0)] "TypeError: Cannot read property 'exceptionDetails' of null", source: (0)

{type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_PLAYING"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_CREATE", name: "GstMessageStreamStatus", owner: "(GstTypeFindElement) typefind", object: "(GstTask) typefind:sink"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_ENTER", name: "GstMessageStreamStatus", owner: "(GstTypeFindElement) typefind", object: "(GstTask) typefind:sink"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_CREATE", name: "GstMessageStreamStatus", owner: "(GstQTDemux) qtdemux2", object: "(GstTask) qtdemux2:sink"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_ENTER", name: "GstMessageStreamStatus", owner: "(GstQTDemux) qtdemux2", object: "(GstTask) qtdemux2:sink"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_CREATE", name: "GstMessageStreamStatus", owner: "(GstMultiQueue) multiqueue2", object: "(GstTask) multiqueue2:src_0"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_ENTER", name: "GstMessageStreamStatus", owner: "(GstMultiQueue) multiqueue2", object: "(GstTask) multiqueue2:src_0"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "decoder", name: "H.264 (High Profile)-Decoder", detail: "video/x-h264, level=(string)4.1, profile=(string)h… bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_CREATE", name: "GstMessageStreamStatus", owner: "(GstMultiQueue) multiqueue2", object: "(GstTask) multiqueue2:src_1"} index.html:19 {type: "GST_STREAM_STATUS_TYPE_ENTER", name: "GstMessageStreamStatus", owner: "(GstMultiQueue) multiqueue2", object: "(GstTask) multiqueue2:src_1"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_NULL", new-state: "GST_STATE_READY", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "duration-changed", name: "GstMessageDurationChanged"} index.html:19 {type: "warning", name: "GstMessageWarning", gerror: undefined, debug: "./grammar.y(506): gst_parse_no_more_pads (): /GstP…some pad of GstAutoVideoSink named autovideosink2"} index.html:19 {type: "state-changed", name: "GstMessageStateChanged", old-state: "GST_STATE_READY", new-state: "GST_STATE_PAUSED", pending-state: "GST_STATE_VOID_PENDING"} index.html:19 {type: "error", name: "/GstPipeline:pipeline2/GstDecodeBin:decodebin2/GstQTDemux:qtdemux2", gerror: undefined, debug: "qtdemux.c(6605): gst_qtdemux_loop (): /GstPipeline…demux2:↵streaming stopped, reason not-linked (-1)", details: "details, flow-return=(int)-1;", …}

One problem about 'get_pipeline_get_latyecy'

../Pipeline.cpp: In static member function ‘static Nan::NAN_GETTER_RETURN_TYPE Pipeline::GetLatency(v8::Local<v8::String>, Nan::NAN_GETTER_ARGS_TYPE)’: ../Pipeline.cpp:215:70: error: ‘gst_pipeline_get_latency’ was not declared in this scope double secs = NANOS_TO_DOUBLE(gst_pipeline_get_latency(obj->pipeline)); ^ ../Pipeline.cpp:12:41: note: in definition of macro ‘NANOS_TO_DOUBLE’ #define NANOS_TO_DOUBLE(nanos)(((double)nanos)/1000000000) ^ ../Pipeline.cpp: In static member function ‘static Nan::NAN_SETTER_RETURN_TYPE Pipeline::SetLatency(v8::Local<v8::String>, v8::Local<v8::Value>, Nan::NAN_SETTER_ARGS_TYPE)’: ../Pipeline.cpp:221:80: error: ‘gst_pipeline_set_latency’ was not declared in this scope gst_pipeline_set_latency(obj->pipeline, DOUBLE_TO_NANOS(value->NumberValue())); ^ gstreamer-superficial.target.mk:101: recipe for target 'Release/obj.target/gstreamer-superficial/Pipeline.o' failed

I build on arm platform with OS ubuntu, my gstreamer include file have not 'gst_pipeline_get_latency' and 'get_pipeline_set_latency', these two method maybe not use usually, would you remove two method?

How to get stream object?

Hi,

I want to get stream object like in the below code:

Stream = require('node-rtsp-stream');
            stream = new Stream({
                    streamUrl: 'rtsp://freja.hiof.no:1935/rtplive/_definst_/hessdalen02.stream',
                    wsPort: 9999
            })
            console.log('[MASTER] created rtsp stream'+JSON.stringify(stream));
            master.localStream = stream;

Is there a way to get stream object using gstreamer-superficial?

Gstreamer pipeline debugging

Is there any opportunity to debug Gstreamer pipeline using log levels and gstreamer's graph system? I mean, I used to debug the pipeline using GST_DEBUG_DUMP_DOT_DIR env var to generate special dot graph. Moreover, it's useful to define special debugging level to see all memory dump or just debug info logs. Are these things somehow possible with this package? Thanks in advance.

node-gyp configure fails on debian beaglebone black.

This may be related to issue #3.

I'm not that familiar with node-gyp. Should it resolve the dependencies? I'll try installing node-gyp and see if this clears this error.

Bash log:
root@bone:/var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial# node-gyp configure
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | linux | arm
gyp info spawn /usr/bin/python2
gyp info spawn args [ '/usr/local/lib/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args 'binding.gyp',
gyp info spawn args '-f',
gyp info spawn args 'make',
gyp info spawn args '-I',
gyp info spawn args '/var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial/build/config.gypi',
gyp info spawn args '-I',
gyp info spawn args '/usr/local/lib/node_modules/node-gyp/addon.gypi',
gyp info spawn args '-I',
gyp info spawn args '/root/.node-gyp/0.12.17/include/node/common.gypi',
gyp info spawn args '-Dlibrary=shared_library',
gyp info spawn args '-Dvisibility=default',
gyp info spawn args '-Dnode_root_dir=/root/.node-gyp/0.12.17',
gyp info spawn args '-Dnode_gyp_dir=/usr/local/lib/node_modules/node-gyp',
gyp info spawn args '-Dnode_lib_file=node.lib',
gyp info spawn args '-Dmodule_root_dir=/var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial',
gyp info spawn args '--depth=.',
gyp info spawn args '--no-parallel',
gyp info spawn args '--generator-output',
gyp info spawn args 'build',
gyp info spawn args '-Goutput_dir=.' ]
module.js:338
throw err;
^
Error: Cannot find module 'nan'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at [eval]:1:1
at Object.exports.runInThisContext (vm.js:74:17)
at Object. ([eval]-wrapper:6:22)
at Module._compile (module.js:460:26)
at evalScript (node.js:431:25)
at startup (node.js:90:7)
gyp: Call to 'node -e "require('nan')"' returned exit status 1 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: gyp failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (/usr/local/lib/node_modules/node-gyp/lib/configure.js:305:16)
gyp ERR! stack at ChildProcess.emit (events.js:110:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:1078:12)
gyp ERR! System Linux 4.4.9-ti-r25
gyp ERR! command "node" "/usr/local/bin/node-gyp" "configure"
gyp ERR! cwd /var/lib/cloud9/Projects/VideoServer/node-gstreamer-superficial
gyp ERR! node -v v0.12.17
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok

A new instance is created when I use pause() and stop() don't work within websocket.io

I am having a simple test for a pipeline where I need to control the stream play(), pause(), and stop() from a client side through websocket events. It works for the most part however, the problem is when I close the client side page (closing the socket) and reopening it I lose the ability to control the stream anymore, I can't pause it or stop it, it does however keep the pipeline running. I noticed it's like opening a new "instance" -new gstreamer window appears with paused image- when I pause() it and that's why it's no longer pausing the previous one.
Note: as long as I keep the page open, I can control the stream with pause/stop
here's a code snipped maybe better explains it or replicating the issue.

https://www.codepile.net/pile/WnKjKOEb

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.