@4players/odin-nodejs 0.7.0

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 (99) hide show
  1. package/.idea/.name +1 -0
  2. package/.idea/jsLibraryMappings.xml +6 -0
  3. package/.idea/misc.xml +4 -0
  4. package/.idea/modules.xml +9 -0
  5. package/.idea/odin-nodejs.iml +8 -0
  6. package/.idea/odin_nodejs.iml +2 -0
  7. package/.idea/php.xml +19 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/CMakeLists.txt +25 -0
  10. package/README.md +53 -0
  11. package/binding.gyp +61 -0
  12. package/build/Makefile +352 -0
  13. package/build/Release/.deps/Release/nothing.a.d +1 -0
  14. package/build/Release/.deps/Release/obj.target/nothing/node_modules/node-addon-api/nothing.o.d +4 -0
  15. package/build/Release/.deps/Release/obj.target/odin/cppsrc/binding.o.d +27 -0
  16. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinbindings.o.d +24 -0
  17. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinclient.o.d +24 -0
  18. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinmedia.o.d +24 -0
  19. package/build/Release/.deps/Release/obj.target/odin/cppsrc/odinroom.o.d +24 -0
  20. package/build/Release/.deps/Release/obj.target/odin/cppsrc/utilities.o.d +21 -0
  21. package/build/Release/.deps/Release/odin.node.d +1 -0
  22. package/build/Release/nothing.a +0 -0
  23. package/build/Release/obj.target/nothing/node_modules/node-addon-api/nothing.o +0 -0
  24. package/build/Release/obj.target/odin/cppsrc/binding.o +0 -0
  25. package/build/Release/obj.target/odin/cppsrc/odinbindings.o +0 -0
  26. package/build/Release/obj.target/odin/cppsrc/odinclient.o +0 -0
  27. package/build/Release/obj.target/odin/cppsrc/odinmedia.o +0 -0
  28. package/build/Release/obj.target/odin/cppsrc/odinroom.o +0 -0
  29. package/build/Release/obj.target/odin/cppsrc/utilities.o +0 -0
  30. package/build/binding.Makefile +6 -0
  31. package/build/gyp-mac-tool +772 -0
  32. package/build/node_modules/node-addon-api/node_api.Makefile +6 -0
  33. package/build/node_modules/node-addon-api/nothing.target.mk +186 -0
  34. package/build/odin.target.mk +201 -0
  35. package/cmake-build-debug/.cmake/api/v1/query/cache-v2 +0 -0
  36. package/cmake-build-debug/.cmake/api/v1/query/cmakeFiles-v1 +0 -0
  37. package/cmake-build-debug/.cmake/api/v1/query/codemodel-v2 +0 -0
  38. package/cmake-build-debug/.cmake/api/v1/query/toolchains-v1 +0 -0
  39. package/cmake-build-debug/.cmake/api/v1/reply/cache-v2-912a6d0c3c2c7ebbadf8.json +1183 -0
  40. package/cmake-build-debug/.cmake/api/v1/reply/cmakeFiles-v1-0825651e80f1fb47890c.json +161 -0
  41. package/cmake-build-debug/.cmake/api/v1/reply/codemodel-v2-bc24edc239de864eb886.json +60 -0
  42. package/cmake-build-debug/.cmake/api/v1/reply/directory-.-Debug-f5ebdc15457944623624.json +14 -0
  43. package/cmake-build-debug/.cmake/api/v1/reply/index-2023-03-18T11-25-22-0179.json +108 -0
  44. package/cmake-build-debug/.cmake/api/v1/reply/target-odin_nodejs-Debug-1ac16802f252a85492c7.json +322 -0
  45. package/cmake-build-debug/.cmake/api/v1/reply/toolchains-v1-b57293a485ebf36c82cc.json +88 -0
  46. package/cmake-build-debug/.ninja_log +1 -0
  47. package/cmake-build-debug/CMakeCache.txt +367 -0
  48. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeCCompiler.cmake +72 -0
  49. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeCXXCompiler.cmake +83 -0
  50. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeDetermineCompilerABI_C.bin +0 -0
  51. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  52. package/cmake-build-debug/CMakeFiles/3.24.2/CMakeSystem.cmake +15 -0
  53. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdC/CMakeCCompilerId.c +838 -0
  54. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdC/CMakeCCompilerId.o +0 -0
  55. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +826 -0
  56. package/cmake-build-debug/CMakeFiles/3.24.2/CompilerIdCXX/CMakeCXXCompilerId.o +0 -0
  57. package/cmake-build-debug/CMakeFiles/CMakeError.log +22 -0
  58. package/cmake-build-debug/CMakeFiles/CMakeOutput.log +250 -0
  59. package/cmake-build-debug/CMakeFiles/TargetDirectories.txt +3 -0
  60. package/cmake-build-debug/CMakeFiles/clion-Debug-log.txt +4 -0
  61. package/cmake-build-debug/CMakeFiles/clion-environment.txt +3 -0
  62. package/cmake-build-debug/CMakeFiles/cmake.check_cache +1 -0
  63. package/cmake-build-debug/CMakeFiles/rules.ninja +74 -0
  64. package/cmake-build-debug/Testing/Temporary/LastTest.log +3 -0
  65. package/cmake-build-debug/build.ninja +205 -0
  66. package/cmake-build-debug/cmake_install.cmake +49 -0
  67. package/cppsrc/binding.cpp +15 -0
  68. package/cppsrc/odinbindings.cpp +58 -0
  69. package/cppsrc/odinbindings.h +9 -0
  70. package/cppsrc/odinclient.cpp +162 -0
  71. package/cppsrc/odinclient.h +17 -0
  72. package/cppsrc/odinmedia.cpp +242 -0
  73. package/cppsrc/odinmedia.h +35 -0
  74. package/cppsrc/odinroom.cpp +738 -0
  75. package/cppsrc/odinroom.h +65 -0
  76. package/cppsrc/utilities.cpp +102 -0
  77. package/cppsrc/utilities.h +175 -0
  78. package/index.cjs +2 -0
  79. package/index.d.ts +5 -0
  80. package/libs/bin/linux/arm64/libodin_static.a +0 -0
  81. package/libs/bin/linux/ia32/libodin_static.a +0 -0
  82. package/libs/bin/linux/x64/libodin_static.a +0 -0
  83. package/libs/bin/macos/arm64/libodin_static.a +0 -0
  84. package/libs/bin/macos/x64/libodin_static.a +0 -0
  85. package/libs/bin/windows/arm64/odin_static.lib +0 -0
  86. package/libs/bin/windows/ia32/odin_static.lib +0 -0
  87. package/libs/bin/windows/x64/odin_static.lib +0 -0
  88. package/libs/include/odin.h +896 -0
  89. package/odin.client.d.ts +22 -0
  90. package/odin.media.d.ts +33 -0
  91. package/odin.room.d.ts +473 -0
  92. package/package.json +50 -0
  93. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  94. package/test.js +211 -0
  95. package/tests/audio-recording/README.md +24 -0
  96. package/tests/audio-recording/index.js +148 -0
  97. package/tests/sending-audio/README.md +20 -0
  98. package/tests/sending-audio/index.js +81 -0
  99. package/tests/sending-audio/santa.mp3 +0 -0
package/test.js ADDED
@@ -0,0 +1,211 @@
1
+ const accessKey = "Ad4R7/hpCx1U5yGvC61oNBeJ/fWiW7dodvXWW7MEwrjg";
2
+ const roomName = "Hallo";
3
+ const userName = "My Bot";
4
+
5
+ import odin from '../../index.cjs';
6
+ const {OdinRoom, OdinClient} = odin;
7
+
8
+ import wav from 'wav';
9
+ import { Configuration, OpenAIApi } from "openai";
10
+ import fs from 'fs';
11
+
12
+ const configuration = new Configuration({
13
+ apiKey: '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'
14
+ });
15
+ const openai = new OpenAIApi(configuration);
16
+
17
+ //const token = odin.generateAccessToken(accessKey, roomName, userName);
18
+ //console.log(token);
19
+
20
+ const userData = {
21
+ name: "Recorder Bot",
22
+ seed: "123",
23
+ userId: "Bot007",
24
+ outputMuted: 1,
25
+ platform: "ODIN JS Bot SDK",
26
+ version: "0.1"
27
+ }
28
+
29
+ const fileRecorder = {};
30
+
31
+ const data = new TextEncoder().encode(JSON.stringify(userData));
32
+
33
+ const odinClient = new OdinClient(accessKey);
34
+ const room2 = odinClient.createRoom(roomName, userName);
35
+
36
+
37
+ //odin.startup();
38
+
39
+ //room2 = odin.initRoom(token);
40
+ room2.setEventListener((event) => {
41
+ console.log(event);
42
+ });
43
+
44
+ room2.addEventListener('PeerJoined', (event) => {
45
+ console.log("Received PeerJoined event", event);
46
+ console.log(JSON.parse(new TextDecoder().decode(event.userData)));
47
+ });
48
+
49
+ room2.addEventListener('PeerLeft', (event) => {
50
+ console.log("Received PeerLeft event", event);
51
+ });
52
+
53
+ room2.addEventListener('MediaActivity', (event) => {
54
+ console.log("Media", event);
55
+ if (event.state) {
56
+ // User started talking
57
+ if (!fileRecorder[event.mediaId]) {
58
+ const timer = new Date().getTime();
59
+ const fileName = `./recording_${event.peerId}_${event.mediaId}_${timer}.wav`;
60
+ console.log(fileName);
61
+ fileRecorder[event.mediaId] = {
62
+ wavEncoder: new wav.FileWriter(fileName, {
63
+ channels: 1,
64
+ sampleRate: 48000,
65
+ bitDepth: 16
66
+ }),
67
+ fileName: fileName
68
+ };
69
+ } else {
70
+ if (fileRecorder[event.mediaId].timer) {
71
+ clearTimeout(fileRecorder[event.mediaId].timer);
72
+ delete fileRecorder[event.mediaId].timer;
73
+ }
74
+ }
75
+ } else {
76
+ // User stopped talking
77
+ if (fileRecorder[event.mediaId]) {
78
+ if (!fileRecorder[event.mediaId].timer) {
79
+ fileRecorder[event.mediaId].timer = setTimeout(() => {
80
+ fileRecorder[event.mediaId].wavEncoder.end();
81
+
82
+ try {
83
+ const file = fs.createReadStream(fileRecorder[event.mediaId].fileName);
84
+ openai.createTranscription(file, "whisper-1").then((response) => {
85
+ console.log("TRANSACTION", response.data.text);
86
+ });
87
+ } catch (e) {
88
+ console.log("Failed to transcribe: ", e);
89
+ }
90
+
91
+
92
+ delete fileRecorder[event.mediaId];
93
+ }, 2000);
94
+ }
95
+ }
96
+ }
97
+ });
98
+
99
+ //const input = prompt('Press any key?');
100
+ //const odinClient = new OdinClient(accessKey);
101
+ //const room2 = new OdinRoom(token);
102
+
103
+ room2.join("gateway.odin.4players.io", data);
104
+
105
+ console.log("ROOM-ID:", room2.id);
106
+
107
+ const message = {
108
+ kind: 'message',
109
+ payload: {
110
+ text: 'Hello World'
111
+ }
112
+ }
113
+
114
+ const fileWriter = new wav.FileWriter('./recording.wav', {
115
+ channels: 1,
116
+ sampleRate: 48000,
117
+ bitDepth: 16
118
+ });
119
+
120
+ room2.addEventListener('AudioDataReceived', (data) => {
121
+ //console.log("Received AudioDataReceived event from peer", data.peerId, "with mediaId", data.mediaId, "and event", data.samples32);
122
+ //console.log(Float32Array.from(data.samples32));
123
+
124
+ // Getting an array of the sample buffer
125
+ /*
126
+ let ui32 = new Float32Array(data.samples32.buffer);
127
+ console.log(ui32);
128
+
129
+ let ui16 = new Int16Array(data.samples16.buffer);
130
+ console.log(ui16);
131
+ */
132
+
133
+ fileWriter.file.write(data.samples16, (error) => {
134
+
135
+ });
136
+
137
+
138
+ if (fileRecorder[data.mediaId]) {
139
+ fileRecorder[data.mediaId].wavEncoder.file.write(data.samples16, (error) => {
140
+ if (error) {
141
+ console.log("Failed to write audio file");
142
+ }
143
+ });
144
+ }
145
+ });
146
+
147
+ room2.sendMessage(new TextEncoder().encode(JSON.stringify(message)));
148
+
149
+ console.log("Press any key to stop");
150
+ const stdin = process.stdin;
151
+ stdin.resume();
152
+ stdin.setEncoding( 'utf8' );
153
+ stdin.on( 'data', function( key )
154
+ {
155
+ console.log("Shutting down");
156
+ room2.close();
157
+ fileWriter.end();
158
+
159
+ process.exit();
160
+ });
161
+
162
+
163
+
164
+ /*
165
+ const room = odin.createRoom();
166
+
167
+ let error = 0;
168
+ try {
169
+ error = odin.joinRoom(room, "gateway.odin.4players.io", token);
170
+ } catch(e) {
171
+ console.log(error);
172
+ console.log(odin.formatError(error));
173
+ }
174
+
175
+ const userData = {
176
+ name: "Recorder Bot",
177
+ seed: "123",
178
+ userId: "Bot007",
179
+ outputMuted: 1,
180
+ platform: "ODIN JS Bot SDK",
181
+ version: "0.1"
182
+ }
183
+
184
+ const data = new TextEncoder().encode(JSON.stringify(userData));
185
+
186
+ odin.updatePeerUserData(room, data);
187
+ */
188
+ //const name = prompt('Press any key?');
189
+ /*
190
+ odin.closeRoom(room);
191
+ odin.destroyRoom(room);
192
+ odin.shutdown();
193
+ */
194
+ /*
195
+
196
+ const tokenGenerator = new TokenGenerator(accessKey);
197
+ const token = tokenGenerator.createToken(roomName, userName);
198
+
199
+ console.log(token);
200
+
201
+ const testAddon = require('./build/Release/testaddon.node')
202
+ console.log(testAddon.hello());
203
+ console.log(testAddon.add(5,10));
204
+
205
+ const classInstance = new testAddon.ClassExample(4.3);
206
+ console.log('Testing class initial value : ',classInstance.getValue());
207
+ console.log('After adding 3.3 : ',classInstance.add(3.3));
208
+
209
+ const odinClient = new testAddon.OdinClient();
210
+ odinClient.joinRoom(accessKey, roomName, userName);
211
+ */
@@ -0,0 +1,24 @@
1
+ # ODIN Node JS Sample "Audio Recording"
2
+
3
+ This sample demonstrates how to use the ODIN SDK to record audio from other users and sending these to OpenAI for
4
+ transcription. It also features basic "Bot" functionality like sending a message to the chat.
5
+
6
+ ## Prerequisites
7
+
8
+ You need to have an ODIN Access Key. See [here](https://www.4players.io/odin/introduction/access-keys/#generating-access-keys))
9
+ for more info on the topic and to create one for free directly in the documentation.
10
+
11
+ This sample also requires an OpenAI API Key for transcription. You can get one for free [here](https://beta.openai.com/).
12
+
13
+ ## Getting Started
14
+
15
+ Run the script with the following command:
16
+
17
+ ```bash
18
+ node index.js
19
+ ```
20
+
21
+ It will connect to the room `Lobby` using your access key and will send a "Hello World" message to the chat. It will
22
+ then wait for users start to talk and will record their audio into a file. The file name will be the user's name with a
23
+ timestamp and will be a WAV file. 2 seconds after the user stops talking, the recording will be stopped and the file
24
+ will be sent to OpenAI for transcription.
@@ -0,0 +1,148 @@
1
+ const accessKey = "__YOUR_ACCESS_KEY__";
2
+ const roomName = "Lobby";
3
+ const userName = "My Bot";
4
+
5
+ // Load the odin module
6
+ import odin from '../../index.cjs';
7
+ const {OdinClient} = odin;
8
+
9
+ // Import wav module and OpenAI API
10
+ import wav from 'wav';
11
+ import { Configuration, OpenAIApi } from "openai";
12
+ import fs from 'fs';
13
+
14
+ // Configure OpenAI - use your own API key
15
+ const configuration = new Configuration({
16
+ apiKey: '__YOUR_OPENAI_API_KEY__'
17
+ });
18
+ const openai = new OpenAIApi(configuration);
19
+
20
+ // Create an odin client instance using our access key and create a room
21
+ const odinClient = new OdinClient(accessKey);
22
+ const room = odinClient.createRoom(roomName, userName);
23
+
24
+ // Listen on PeerJoined messages and print the user data of the joined peer
25
+ room.addEventListener('PeerJoined', (event) => {
26
+ console.log("Received PeerJoined event", event);
27
+ console.log(JSON.parse(new TextDecoder().decode(event.userData)));
28
+ });
29
+
30
+ // Listen on PeerLeft messages and print the user data of the left peer
31
+ room.addEventListener('PeerLeft', (event) => {
32
+ console.log("Received PeerLeft event", event);
33
+ });
34
+
35
+ // Listen on MediaActivity messages and prepare a wav file for each media stream. The basic idea here is to
36
+ // create a WAV encoder file whenever a users starts talking and to close the file when the user stops talking. This way,
37
+ // we have isolated WAV files for each user and can transcribe them individually. If we don't want to create new files
38
+ // during short pauses, we wait 2 seconds before closing the file.
39
+ room.addEventListener('MediaActivity', (event) => {
40
+ if (event.state) {
41
+ // User started talking - prepare a new file
42
+ if (!fileRecorder[event.mediaId]) {
43
+ const timer = new Date().getTime();
44
+ const fileName = `./recording_${event.peerId}_${event.mediaId}_${timer}.wav`;
45
+ console.log("Created a new recording file: ", fileName);
46
+ fileRecorder[event.mediaId] = {
47
+ wavEncoder: new wav.FileWriter(fileName, {
48
+ channels: 1,
49
+ sampleRate: 48000,
50
+ bitDepth: 16
51
+ }),
52
+ fileName: fileName
53
+ };
54
+ } else {
55
+ // We already have a file for this media stream - reset the timer to avoid closing the file
56
+ if (fileRecorder[event.mediaId].timer) {
57
+ clearTimeout(fileRecorder[event.mediaId].timer);
58
+ delete fileRecorder[event.mediaId].timer;
59
+ }
60
+ }
61
+ } else {
62
+ // User stopped talking
63
+ if (fileRecorder[event.mediaId]) {
64
+ // If we don't have a timer yet, create one
65
+ if (!fileRecorder[event.mediaId].timer) {
66
+ fileRecorder[event.mediaId].timer = setTimeout(() => {
67
+ // The timer timed out - i.e. the user did stop talking for 2 seconds - close the file
68
+ fileRecorder[event.mediaId].wavEncoder.end();
69
+
70
+ // Transcribe the file using OpenAI
71
+ try {
72
+ const file = fs.createReadStream(fileRecorder[event.mediaId].fileName);
73
+ openai.createTranscription(file, "whisper-1").then((response) => {
74
+ console.log("OpenAI Transcription: ", response.data.text);
75
+ });
76
+ } catch (e) {
77
+ console.log("Failed to transcribe: ", e);
78
+ }
79
+
80
+ // Delete the file recorder object
81
+ delete fileRecorder[event.mediaId];
82
+ }, 2000);
83
+ }
84
+ }
85
+ }
86
+ });
87
+
88
+ // Configure user data used by the bot - this user data will be compatible with ODIN Web Client (https://odin.4players.de/app).
89
+ const userData = {
90
+ name: "Recorder Bot",
91
+ seed: "123",
92
+ userId: "Bot007",
93
+ outputMuted: 1,
94
+ platform: "ODIN JS Bot SDK",
95
+ version: "0.1"
96
+ }
97
+ // Create a byte array from the user data (ODIN uses byte arrays for user data for maximum flexibility)
98
+ const data = new TextEncoder().encode(JSON.stringify(userData));
99
+
100
+ // Join the room using the default gateway and our user data
101
+ room.join("gateway.odin.4players.io", data);
102
+
103
+ // Print the room-id
104
+ console.log("ROOM-ID:", room.id);
105
+
106
+ // Add an event filter for audio data received events
107
+ room.addEventListener('AudioDataReceived', (data) => {
108
+ // Getting an array of the sample buffer - use for example to visualize audio
109
+ /*
110
+ let ui32 = new Float32Array(data.samples32.buffer);
111
+ console.log(ui32);
112
+
113
+ let ui16 = new Int16Array(data.samples16.buffer);
114
+ console.log(ui16);
115
+ */
116
+
117
+ // Write the audio data to the file using a WAV encoder
118
+ if (fileRecorder[data.mediaId]) {
119
+ fileRecorder[data.mediaId].wavEncoder.file.write(data.samples16, (error) => {
120
+ if (error) {
121
+ console.log("Failed to write audio file");
122
+ }
123
+ });
124
+ }
125
+ });
126
+
127
+ // Prepare a message compatible with the ODIN Web Client and send it to all users (see @4players/odin-foundation for more info)
128
+ const message = {
129
+ kind: 'message',
130
+ payload: {
131
+ text: 'Hello World'
132
+ }
133
+ }
134
+ room.sendMessage(new TextEncoder().encode(JSON.stringify(message)));
135
+
136
+ // Wait for a key press to stop the script
137
+ console.log("Press any key to stop");
138
+ const stdin = process.stdin;
139
+ stdin.resume();
140
+ stdin.setEncoding( 'utf8' );
141
+ stdin.on( 'data', function( key )
142
+ {
143
+ console.log("Shutting down");
144
+ room.close();
145
+ fileWriter.end();
146
+
147
+ process.exit();
148
+ });
@@ -0,0 +1,20 @@
1
+ # ODIN Send Music Example
2
+
3
+ This sample demonstrates how to use the ODIN SDK to send music to other users in a room. It loads a sample MP3 file,
4
+ decodes it and sends it to the ODIN server.
5
+
6
+ ## Prerequisites
7
+
8
+ You need to have an ODIN Access Key. See [here](https://www.4players.io/odin/introduction/access-keys/#generating-access-keys))
9
+ for more info on the topic and to create one for free directly in the documentation.
10
+
11
+ ## Getting Started
12
+
13
+ Run the script with the following command:
14
+
15
+ ```bash
16
+ node index.js
17
+ ```
18
+
19
+ It will connect to the room `Lobby` using your access key and will send a "Hello World" message to the chat. It will then
20
+ start sending an MP3 file into the room.
@@ -0,0 +1,81 @@
1
+ const accessKey = "__YOUR_ACCESS_KEY__";
2
+ const roomName = "Lobby";
3
+ const userName = "My Bot";
4
+
5
+ // Load the odin module and other libs
6
+ import odin from '../../index.cjs';
7
+ const {OdinClient} = odin;
8
+ import fs from 'fs';
9
+ import decode, {decoders} from 'audio-decode';
10
+ import AudioBufferStream from 'audio-buffer-stream';
11
+
12
+ // Create an odin client instance using our access key and create a room
13
+ const userData = {
14
+ name: "Music Bot",
15
+ avatar: "https://avatars.dicebear.com/api/bottts/123.svg?backgroundColor=%23333333&textureChance=0&margin=10",
16
+ seed: "123",
17
+ userId: "Bot007",
18
+ outputMuted: 1,
19
+ inputMuted: 0,
20
+ platform: "ODIN JS Bot SDK",
21
+ version: "0.1"
22
+ }
23
+ const data = new TextEncoder().encode(JSON.stringify(userData));
24
+ const odinClient = new OdinClient(accessKey, 44100, 1);
25
+ const room = odinClient.createRoom(roomName, userName);
26
+
27
+ // Join the room
28
+ room.join("gateway.odin.4players.io", data);
29
+
30
+ // Send a message to the room
31
+ const message = {
32
+ kind: 'message',
33
+ payload: {
34
+ text: 'Hello, I am a music bot and will stream some music to you.'
35
+ }
36
+ }
37
+ room.sendMessage(new TextEncoder().encode(JSON.stringify(message)));
38
+
39
+ // Send music to the room
40
+ const sendMusic = async (media) => {
41
+ // Prepare our MP3 decoder and load the sample file
42
+ const audioBuffer = await decode(fs.readFileSync('./santa.mp3'));
43
+
44
+ // Print our some info about the audio file
45
+ console.log(audioBuffer);
46
+
47
+ // Create a stream that will match the settings of the file
48
+ const audioBufferStream = new AudioBufferStream({channels: 1, sampleRate: 44100, float: true, bitDepth: 32});
49
+
50
+ // Whenever the stream has data, send it to the media stream
51
+ audioBufferStream.on('data', (data) => {
52
+ const floats = new Float32Array(new Uint8Array(data).buffer)
53
+ media.sendAudioData(floats);
54
+ });
55
+
56
+ audioBufferStream.write(audioBuffer);
57
+ }
58
+
59
+ // Create a media stream in the room - it will return an OdinMedia instance that we can use to send data to ODIN
60
+ const media = room.createAudioStream(44100, 1);
61
+ console.log(media);
62
+ console.log("MEDIA-ID:", media.id);
63
+
64
+ // Start the stream and send the music to ODIN
65
+ sendMusic(media).then(() => {
66
+ console.log("Finished sending song");
67
+ });
68
+
69
+ // Wait until the user presses a key to stop
70
+ console.log("Press any key to stop");
71
+ const stdin = process.stdin;
72
+ stdin.resume();
73
+ stdin.setEncoding( 'utf8' );
74
+ stdin.on( 'data', function( key )
75
+ {
76
+ console.log("Shutting down");
77
+ room.close();
78
+
79
+ process.exit();
80
+ });
81
+
Binary file