getnamo/NodeJs-Unreal

where do we add node packages?

Opened this issue · 24 comments

where do we add node packages? do we simply just use npm init and initialize a new node application inside of /Content/Scripts?

I believe the default folder is {your project root}/Content/Scripts/ that would be where you add a package.json and either run npm i or let the plugin automatically sync your node_modules to your packages.json (see https://github.com/getnamo/nodejs-ue4#npm-modules)

Is there a way to then, take some data from NodeJS-UE4 and pass it to an audio component? I have some binary data which is audio data, but I'm not sure how I could get an audio component from here

You want to emit an ipc event from your script with your data: https://github.com/getnamo/nodejs-ue4#a-basic-adder and receive that in the node.js component, then you forward that data to your audio component (you may need to have a conversion to byte formats that can be easily converted for soundwave e.g. wav)

You want to emit an ipc event from your script with your data: https://github.com/getnamo/nodejs-ue4#a-basic-adder and receive that in the node.js component, then you forward that data to your audio component (you may need to have a conversion to byte formats that can be easily converted for soundwave e.g. wav)

That sounds interesting. Is there a way to send data usinng this: https://github.com/Gielert/NoodleJS into my audio component? I want to essentially write a script using that npm package that will connect to my mumble voice server, and then join a channel (handled by that package), and then take the data from there and send it to the audio component:

client.voiceConnection.playStream(somestream);

I can send data from a stream in javascript using this method. And then I can read it by using readStream()

LogTemp: Error: Script Error: internal/modules/cjs/loader.js:960
  throw err;
  ^
Error: Cannot find module 'mumble'
Require stack:
- C:\Users\decil\Desktop\HVS_Game\Content\Scripts\chat_test.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957:15)
    at Function.Module._load (internal/modules/cjs/loader.js:840:27)
    at Module.require (internal/modules/cjs/loader.js:1019:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> (C:\Users\decil\Desktop\HVS_Game\Content\Scripts\chat_test.js:1:14)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\decil\\Desktop\\HVS_Game\\Content\\Scripts\\chat_test.js'
  ]
}

So I got this error when trying to require the mumble module. I'm using this: https://github.com/Rantanen/node-mumble as well as its example script

Did you manually install it via npm or let the plugin install it? Double check you have a matching embedded node.js to the module, since the embedded node.js may be newer than the module based on age of github shown.

Did you manually install it via npm or let the plugin install it? Double check you have a matching embedded node.js to the module, since the embedded node.js may be newer than the module based on age of github shown.

I just ran npm install mumble in the command prompt.

Hmm that likely used your installed npm/node instead of the one embedded in the plugin. Try letting the plugin install it by adding your module to the package.json inside same folder as scripts.

What version of node is included with the plugin? The person who made this npm package says it only works with node 10

Hmm that likely used your installed npm/node instead of the one embedded in the plugin. Try letting the plugin install it by adding your module to the package.json inside same folder as scripts.

I'll try this out. Also, I noticed you use socket.io for sending the data to the ue4 client. I plan on using this to connect to a mumble voice chat server to handle voice chat in my game, my game is multiplayer but I don't think the server will need to compile any of the node code. Do you think there will be any problems that you could think of so I could plan moving forward?

Also I know you can send the data FROM Node in the link you provided, but what about sending data from UE to the Node plugin? Is this possible? I need to be able to send incoming voice data to my audio component, and then use unreal's FAudioCapture to send data TO other people in the channel using your plugin. Is this possible?

image
This is my package.json file in my project

Looks like you are right. I tried to let the plugin install it and this happened:

LogTemp: Error: Script Error: C:\Users\decil\Desktop\HVS_Game\Content\Scripts\node_modules\bindings\bindings.js:83
        throw e
        ^
Error: The module '\\?\C:\Users\decil\Desktop\HVS_Game\Content\Scripts\node_modules\jitterbuffer\build\Release\node-jitterbuffer.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 64. This version of Node.js requires
NODE_MODULE_VERSION 72. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:1183:18)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)
    at Module.require (internal/modules/cjs/loader.js:1019:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at bindings (C:\Users\decil\Desktop\HVS_Game\Content\Scripts\node_modules\bindings\bindings.js:76:44)
    at Object.<anonymous> (C:\Users\decil\Desktop\HVS_Game\Content\Scripts\node_modules\jitterbuffer\index.js:2:39)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)

Go to https://nodejs.org/en/download/, download an older matching node (zip version) and replace the one in your plugin root/source/nodejs-ue4/Thirdparty folder. You may need to npm i in that folder to update base dependencies for new embed.

Also since you want to stream VoIP, I'd recommend to directly stream bytes into unreal by hosting a socketio server in your node.js part and connecting using the socketio client. That protocol supports raw byte transmission, while I'm unsure if ipc event emitter reroute does in node.js ue4.

Well, for the server I'm using Murmur (Mumble) which is basically an open source VOIP server with channel support and text chat. It has an SDK and that module (linked above) can integrate with it. So on the client side it's just going to connect to the dedicated mumble server, join a channel and let the player send or listen for data (people talking). I'll look into it, and I'll also try to download the version you mentioned.

Go to https://nodejs.org/en/download/, download an older matching node (zip version) and replace the one in your plugin root/source/nodejs-ue4/Thirdparty folder. You may need to npm i in that folder to update base dependencies for new embed.

Also since you want to stream VoIP, I'd recommend to directly stream bytes into unreal by hosting a socketio server in your node.js part and connecting using the socketio client. That protocol supports raw byte transmission, while I'm unsure if ipc event emitter reroute does in node.js ue4.

Great news by the w ay, downloading node 10 works and I was able to connect to my mumble server using that npm package. However, I worry I may be missing out on not having access to Node 12. Do you plan on adding support for multiple versions of Node? Perhaps it could first check with the newest version and then check another folder for other versions?

I'm not sure if Node 10 supports ipc-event-emitter

image
Found this, couldn't figure it out. I noticed the IPC event emitter essentially sends everything as a json object, but I need it to be rawPCM data, or something usable by USoundWave, any ideas?

I believe you're right. ATM I think the plugin doesn't have a raw byte path, this would be a good enhancement.

It's why I currently recommend using a socketio host on your node.js side and use the socket.io client plugin component (which is included in the nodejs plugin release) directly to connect to your node.js script. That plugin protocol does support raw bytes and you can interweave them in objects if you wanted too.

Keep in mind the utility to convert opus bytes to wav is not a standard opus codec format (I'm doing a custom opus minimal struct here). My guess is your mumble emits a pcm stream, you'd need to encapsulate that into a wav packet on node.js side and emit that to ue4 which can then use wav to soundwave to play the audio. For performance reasons, once you have that running considering doing everything but the soundwave instantiation on a background thread (network thread should be sufficient)

I believe you're right. ATM I think the plugin doesn't have a raw byte path, this would be a good enhancement.

It's why I currently recommend using a socketio host on your node.js side and use the socket.io client plugin component (which is included in the nodejs plugin release) directly to connect to your node.js script. That plugin protocol does support raw bytes and you can interweave them in objects if you wanted too.

Do you think it might be better to play audio from mumble on unreal, or javascript directly? I was looking through the socket.io and when you bind an event in unreal it looks like it still takes the events as a string.
image

Depends on whether you want to spatialize the audio. If so you'd want it in unreal so the engine can place it in 3d space. If not it's probably easier to play directly in node.js.

Socket.io plugin does support binary values and it autoconverts into siojson values which do support binary interweaving (without extra serialization steps). I use this type of setup very often myself and consider it fairly robust. See decoding section of the readme of the plugin for details.

Depends on whether you want to spatialize the audio. If so you'd want it in unreal so the engine can place it in 3d space. If not it's probably easier to play directly in node.js.

Socket.io plugin does support binary values and it autoconverts into siojson values which do support binary interweaving (without extra serialization steps). I use this type of setup very often myself and consider it fairly robust. See decoding section of the readme of the plugin for details.

Do you know how to play RawPCM data in JavaScript?

Depends on whether you want to spatialize the audio. If so you'd want it in unreal so the engine can place it in 3d space. If not it's probably easier to play directly in node.js.

Socket.io plugin does support binary values and it autoconverts into siojson values which do support binary interweaving (without extra serialization steps). I use this type of setup very often myself and consider it fairly robust. See decoding section of the readme of the plugin for details.

I was wondering if there is a way to have unreal SEND data to the node script. For example, I have a game server, and it's going to tell players which channel to connect to dependent on the team they are on. However, I have no way of really getting this data from the game server, to nodejs, so then I can use this node package to connect to a specific voice channel. Is it only a one way connection? Is there a bi-directional way of passing data back and forth?

It's bi directional of course. Use IPC event emitter and add an event that you can call and then emit on your nodejs plugins component with the same event name (see this plugin readme for example syntax, e.g. https://github.com/getnamo/nodejs-ue4#a-basic-adder)

If you're connecting directly via socketio, it's the same concept.