pipewire 1.3.0 → 2.0.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 (120) hide show
  1. package/README.md +29 -9
  2. package/dist/bindings/context.d.ts +20 -0
  3. package/dist/bindings/context.d.ts.map +1 -0
  4. package/dist/bindings/context.js +12 -0
  5. package/dist/bindings/context.js.map +1 -0
  6. package/dist/bindings/core.d.ts +34 -0
  7. package/dist/bindings/core.d.ts.map +1 -0
  8. package/dist/bindings/core.js +36 -0
  9. package/dist/bindings/core.js.map +1 -0
  10. package/dist/bindings/dict.d.ts +3 -0
  11. package/dist/bindings/dict.d.ts.map +1 -0
  12. package/dist/bindings/dict.js +11 -0
  13. package/dist/bindings/dict.js.map +1 -0
  14. package/dist/bindings/hook.d.ts +3 -0
  15. package/dist/bindings/hook.d.ts.map +1 -0
  16. package/dist/bindings/hook.js +14 -0
  17. package/dist/bindings/hook.js.map +1 -0
  18. package/dist/bindings/index.d.ts +32 -0
  19. package/dist/bindings/index.d.ts.map +1 -0
  20. package/dist/bindings/index.js +16 -0
  21. package/dist/bindings/index.js.map +1 -0
  22. package/dist/bindings/list.d.ts +2 -0
  23. package/dist/bindings/list.d.ts.map +1 -0
  24. package/dist/bindings/list.js +7 -0
  25. package/dist/bindings/list.js.map +1 -0
  26. package/dist/bindings/loop.d.ts +33 -0
  27. package/dist/bindings/loop.d.ts.map +1 -0
  28. package/dist/bindings/loop.js +17 -0
  29. package/dist/bindings/loop.js.map +1 -0
  30. package/dist/bindings/main-loop.d.ts +47 -0
  31. package/dist/bindings/main-loop.d.ts.map +1 -0
  32. package/dist/bindings/main-loop.js +15 -0
  33. package/dist/bindings/main-loop.js.map +1 -0
  34. package/dist/bindings/node.d.ts +50 -0
  35. package/dist/bindings/node.d.ts.map +1 -0
  36. package/dist/bindings/node.js +81 -0
  37. package/dist/bindings/node.js.map +1 -0
  38. package/dist/bindings/param.d.ts +25 -0
  39. package/dist/bindings/param.d.ts.map +1 -0
  40. package/dist/bindings/param.js +33 -0
  41. package/dist/bindings/param.js.map +1 -0
  42. package/dist/bindings/pipewire.d.ts +19 -0
  43. package/dist/bindings/pipewire.d.ts.map +1 -0
  44. package/dist/bindings/pipewire.js +5 -0
  45. package/dist/bindings/pipewire.js.map +1 -0
  46. package/dist/bindings/pod.d.ts +2 -0
  47. package/dist/bindings/pod.d.ts.map +1 -0
  48. package/dist/bindings/pod.js +6 -0
  49. package/dist/bindings/pod.js.map +1 -0
  50. package/dist/bindings/properties.d.ts +2 -0
  51. package/dist/bindings/properties.d.ts.map +1 -0
  52. package/dist/bindings/properties.js +3 -0
  53. package/dist/bindings/properties.js.map +1 -0
  54. package/dist/bindings/props.d.ts +59 -0
  55. package/dist/bindings/props.d.ts.map +1 -0
  56. package/dist/bindings/props.js +59 -0
  57. package/dist/bindings/props.js.map +1 -0
  58. package/dist/bindings/proxy.d.ts +11 -0
  59. package/dist/bindings/proxy.d.ts.map +1 -0
  60. package/dist/bindings/proxy.js +5 -0
  61. package/dist/bindings/proxy.js.map +1 -0
  62. package/dist/bindings/registry.d.ts +20 -0
  63. package/dist/bindings/registry.d.ts.map +1 -0
  64. package/dist/bindings/registry.js +19 -0
  65. package/dist/bindings/registry.js.map +1 -0
  66. package/dist/bindings/thread-loop.d.ts +65 -0
  67. package/dist/bindings/thread-loop.d.ts.map +1 -0
  68. package/dist/bindings/thread-loop.js +18 -0
  69. package/dist/bindings/thread-loop.js.map +1 -0
  70. package/dist/index.d.ts +5 -13
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +5 -13
  73. package/dist/index.js.map +1 -1
  74. package/dist/loop.d.ts +27 -0
  75. package/dist/loop.d.ts.map +1 -1
  76. package/dist/loop.js +4 -0
  77. package/dist/loop.js.map +1 -1
  78. package/dist/node.d.ts +53 -39
  79. package/dist/node.d.ts.map +1 -1
  80. package/dist/node.js +104 -69
  81. package/dist/node.js.map +1 -1
  82. package/dist/object.d.ts +18 -0
  83. package/dist/object.d.ts.map +1 -0
  84. package/dist/object.js +22 -0
  85. package/dist/object.js.map +1 -0
  86. package/dist/pipewire.d.ts +50 -15
  87. package/dist/pipewire.d.ts.map +1 -1
  88. package/dist/pipewire.js +94 -3
  89. package/dist/pipewire.js.map +1 -1
  90. package/dist/thread-loop.d.ts +65 -0
  91. package/dist/thread-loop.d.ts.map +1 -0
  92. package/dist/thread-loop.js +18 -0
  93. package/dist/thread-loop.js.map +1 -0
  94. package/examples/basic.ts +20 -0
  95. package/examples/{event-registry.ts → event-registry-async.ts} +13 -6
  96. package/examples/event-registry-sync.ts +60 -0
  97. package/examples/node-events.ts +34 -0
  98. package/package.json +1 -1
  99. package/src/{core.ts → bindings/core.ts} +8 -6
  100. package/src/bindings/index.ts +16 -0
  101. package/src/{loop.ts → bindings/loop.ts} +6 -0
  102. package/src/bindings/node.ts +92 -0
  103. package/src/bindings/param.ts +33 -0
  104. package/src/bindings/pipewire.ts +6 -0
  105. package/src/{registry.ts → bindings/registry.ts} +2 -0
  106. package/src/bindings/thread-loop.ts +23 -0
  107. package/src/index.ts +5 -13
  108. package/src/node.ts +167 -79
  109. package/src/object.ts +36 -0
  110. package/src/pipewire.ts +154 -3
  111. package/src/param.ts +0 -33
  112. /package/src/{context.ts → bindings/context.ts} +0 -0
  113. /package/src/{dict.ts → bindings/dict.ts} +0 -0
  114. /package/src/{hook.ts → bindings/hook.ts} +0 -0
  115. /package/src/{list.ts → bindings/list.ts} +0 -0
  116. /package/src/{main-loop.ts → bindings/main-loop.ts} +0 -0
  117. /package/src/{pod.ts → bindings/pod.ts} +0 -0
  118. /package/src/{properties.ts → bindings/properties.ts} +0 -0
  119. /package/src/{props.ts → bindings/props.ts} +0 -0
  120. /package/src/{proxy.ts → bindings/proxy.ts} +0 -0
package/src/pipewire.ts CHANGED
@@ -1,6 +1,157 @@
1
+ import EventEmitter from "node:events";
1
2
  import koffi from "koffi";
3
+ import pw from "./bindings/index.js";
4
+ import PipewireObject from "./object.js";
5
+ import PipewireNode from "./node.js";
2
6
 
3
- const pipewire = koffi.load("libpipewire-0.3.so.0");
7
+ export default class Pipewire extends EventEmitter {
8
+ mainLoop: unknown;
9
+ loop: unknown;
10
+ context: unknown;
11
+ core: unknown;
12
+ registry: unknown;
4
13
 
5
- export const pw_init = pipewire.func("pw_init", "void", ["int**", "char***"]);
6
- export const pw_deinit = pipewire.func("pw_deinit", "void", []);
14
+ registry_listener: Buffer;
15
+ registryEvents: Buffer;
16
+ registryEventGlobalRegister: bigint;
17
+ registryEventGlobalRemoveRegister: bigint;
18
+
19
+ loopInterval: NodeJS.Timeout | null = null;
20
+
21
+ objects: { [id: number]: PipewireObject } = {};
22
+
23
+ constructor() {
24
+ super();
25
+
26
+ pw.pipewire.pw_init(0, null);
27
+
28
+ this.mainLoop = pw.main_loop.pw_main_loop_new(null);
29
+ this.loop = pw.main_loop.pw_main_loop_get_loop(this.mainLoop);
30
+ this.context = pw.context.pw_context_new(this.loop, null, 0);
31
+ this.core = pw.core.pw_context_connect(this.context, null, 0);
32
+ this.registry = pw.core.pw_core_get_registry(this.core, pw.core.PW_VERSION_REGISTRY, 0);
33
+
34
+ this.registry_listener = Buffer.alloc(koffi.sizeof(pw.hook.spa_hook));
35
+ this.registryEvents = Buffer.alloc(koffi.sizeof(pw.core.pw_registry_events));
36
+ this.registryEventGlobalRegister = koffi.register(
37
+ this.registryEventGlobal.bind(this),
38
+ koffi.pointer(pw.core.pw_registry_events_global)
39
+ );
40
+ this.registryEventGlobalRemoveRegister = koffi.register(
41
+ this.registryEventGlobalRemove.bind(this),
42
+ koffi.pointer(pw.core.pw_registry_events_global_remove)
43
+ );
44
+ koffi.encode(this.registryEvents, pw.core.pw_registry_events, {
45
+ version: pw.registry.PW_VERSION_REGISTRY_EVENTS,
46
+ global: this.registryEventGlobalRegister,
47
+ global_remove: this.registryEventGlobalRemoveRegister
48
+ });
49
+ pw.registry.pw_registry_add_listener(this.registry, this.registry_listener, this.registryEvents, null);
50
+ }
51
+
52
+ registryEventGlobal(
53
+ _data: unknown,
54
+ id: number,
55
+ permissions: number,
56
+ type: string,
57
+ version: number,
58
+ props: unknown
59
+ ): void {
60
+ this.emit("rawObjectAdded", { id, permissions, type, version, props });
61
+
62
+ if (this.objects[id]) throw new Error(`Object with id ${id} already exists`);
63
+
64
+ const propsDict = koffi.decode(props, pw.dict.spa_dict);
65
+ const propsArray = koffi.decode(propsDict.items, pw.dict.spa_dict_item, propsDict.n_items);
66
+
67
+ const propsObj: { [key: string]: string } = {};
68
+ for (const item of propsArray) propsObj[item.key] = item.value;
69
+
70
+ if (type === "PipeWire:Interface:Node")
71
+ this.objects[id] = new PipewireNode(this, id, permissions, type, version, propsObj);
72
+ else this.objects[id] = new PipewireObject(this, id, permissions, type, version, propsObj);
73
+ this.emit("objectAdded", this.objects[id]);
74
+ }
75
+
76
+ registryEventGlobalRemove(_data: unknown, id: number): void {
77
+ this.emit("rawObjectRemoved", { id });
78
+
79
+ if (!this.objects[id]) throw new Error(`Object with id ${id} does not exist`);
80
+ this.objects[id].removed = true;
81
+
82
+ if (this.objects[id] instanceof PipewireNode && this.objects[id].nodeProxy) this.objects[id].detachListener();
83
+
84
+ this.emit("objectRemoved", this.objects[id]);
85
+ delete this.objects[id];
86
+ }
87
+
88
+ startLoop(pollInterval: number = 10, pollTimeout: number = 1): void {
89
+ if (this.loopInterval) throw new Error("Loop already started");
90
+ pw.loop.pw_loop_enter(this.loop);
91
+ this.loopInterval = setInterval(() => pw.loop.pw_loop_iterate(this.loop, pollTimeout), pollInterval);
92
+ }
93
+
94
+ stopLoop(): void {
95
+ if (!this.loopInterval) throw new Error("Loop not started");
96
+ clearInterval(this.loopInterval);
97
+ this.loopInterval = null;
98
+ pw.loop.pw_loop_leave(this.loop);
99
+ }
100
+
101
+ on(event: "objectAdded", listener: (object: PipewireObject) => void): this;
102
+ on(event: "objectRemoved", listener: (object: PipewireObject) => void): this;
103
+ on(event: "rawObjectAdded", listener: (data: RawObjectAdded) => void): this;
104
+ on(event: "rawObjectRemoved", listener: (data: RawObjectRemoved) => void): this;
105
+ on(event: string | symbol, listener: (...args: any[]) => void): this;
106
+ on(event: string | symbol, listener: (...args: any[]) => void): this {
107
+ return super.on(event, listener);
108
+ }
109
+
110
+ once(event: "objectAdded", listener: (object: PipewireObject) => void): this;
111
+ once(event: "objectRemoved", listener: (object: PipewireObject) => void): this;
112
+ once(event: "rawObjectAdded", listener: (data: RawObjectAdded) => void): this;
113
+ once(event: "rawObjectRemoved", listener: (data: RawObjectRemoved) => void): this;
114
+ once(event: string | symbol, listener: (...args: any[]) => void): this;
115
+ once(event: string | symbol, listener: (...args: any[]) => void): this {
116
+ return super.once(event, listener);
117
+ }
118
+
119
+ off(event: "objectAdded", listener: (object: PipewireObject) => void): this;
120
+ off(event: "objectRemoved", listener: (object: PipewireObject) => void): this;
121
+ off(event: "rawObjectAdded", listener: (data: RawObjectAdded) => void): this;
122
+ off(event: "rawObjectRemoved", listener: (data: RawObjectRemoved) => void): this;
123
+ off(event: string | symbol, listener: (...args: any[]) => void): this;
124
+ off(event: string | symbol, listener: (...args: any[]) => void): this {
125
+ return super.off(event, listener);
126
+ }
127
+
128
+ emit(event: "objectAdded", object: PipewireObject): boolean;
129
+ emit(event: "objectRemoved", object: PipewireObject): boolean;
130
+ emit(event: "rawObjectAdded", data: RawObjectAdded): boolean;
131
+ emit(event: "rawObjectRemoved", data: RawObjectRemoved): boolean;
132
+ emit(event: string | symbol, ...args: any[]): boolean;
133
+ emit(event: string | symbol, ...args: any[]): boolean {
134
+ return super.emit(event, ...args);
135
+ }
136
+
137
+ deinit(): void {
138
+ pw.proxy.pw_proxy_destroy(this.registry);
139
+ koffi.unregister(this.registryEventGlobalRegister);
140
+ koffi.unregister(this.registryEventGlobalRemoveRegister);
141
+ pw.core.pw_core_disconnect(this.core);
142
+ pw.context.pw_context_destroy(this.context);
143
+ pw.main_loop.pw_main_loop_destroy(this.mainLoop);
144
+ }
145
+ }
146
+
147
+ export type RawObjectAdded = {
148
+ id: number;
149
+ permissions: number;
150
+ type: string;
151
+ version: number;
152
+ props: unknown;
153
+ };
154
+
155
+ export type RawObjectRemoved = {
156
+ id: number;
157
+ };
package/src/param.ts DELETED
@@ -1,33 +0,0 @@
1
- import koffi from "koffi";
2
-
3
- export const spa_param_info = koffi.struct("spa_param_info", {
4
- id: "uint32_t",
5
- flags: "uint32_t",
6
- user: "uint32_t",
7
- seq: "int32_t",
8
- padding: koffi.array("uint32_t", 4)
9
- });
10
-
11
- export const spa_param_type = {
12
- SPA_PARAM_Invalid: 0,
13
- SPA_PARAM_PropInfo: 1,
14
- SPA_PARAM_Props: 2,
15
- SPA_PARAM_EnumFormat: 3,
16
- SPA_PARAM_Format: 4,
17
- SPA_PARAM_Buffers: 5,
18
- SPA_PARAM_Meta: 6,
19
- SPA_PARAM_IO: 7,
20
- SPA_PARAM_EnumProfile: 8,
21
- SPA_PARAM_Profile: 9,
22
- SPA_PARAM_EnumPortConfig: 10,
23
- SPA_PARAM_PortConfig: 11,
24
- SPA_PARAM_EnumRoute: 12,
25
- SPA_PARAM_Route: 13,
26
- SPA_PARAM_Control: 14,
27
- SPA_PARAM_Latency: 15,
28
- SPA_PARAM_ProcessLatency: 16,
29
- SPA_PARAM_Tag: 17,
30
- SPA_PARAM_PeerEnumFormat: 18,
31
- SPA_PARAM_Capability: 19,
32
- SPA_PARAM_PeerCapability: 20
33
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes