@moq/publish 0.1.1 → 0.2.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.
- package/broadcast.d.ts +2 -2
- package/element.d.ts +17 -7
- package/element.d.ts.map +1 -1
- package/element.js +117 -88
- package/element.js.map +1 -1
- package/index.js +2 -2
- package/package.json +3 -3
- package/{screen-Dz_GBTAe.js → screen-BZp2qFyj.js} +4 -4
- package/{screen-Dz_GBTAe.js.map → screen-BZp2qFyj.js.map} +1 -1
- package/ui/index.js +197 -197
- package/ui/index.js.map +1 -1
package/broadcast.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import * as Video from "./video";
|
|
|
9
9
|
export type BroadcastProps = {
|
|
10
10
|
connection?: Moq.Connection.Established | Signal<Moq.Connection.Established | undefined>;
|
|
11
11
|
enabled?: boolean | Signal<boolean>;
|
|
12
|
-
|
|
12
|
+
name?: Moq.Path.Valid | Signal<Moq.Path.Valid | undefined>;
|
|
13
13
|
audio?: Audio.EncoderProps;
|
|
14
14
|
video?: Video.Props;
|
|
15
15
|
location?: Location.Props;
|
|
@@ -22,7 +22,7 @@ export declare class Broadcast {
|
|
|
22
22
|
static readonly CATALOG_TRACK = "catalog.json";
|
|
23
23
|
connection: Signal<Moq.Connection.Established | undefined>;
|
|
24
24
|
enabled: Signal<boolean>;
|
|
25
|
-
|
|
25
|
+
name: Signal<Moq.Path.Valid | undefined>;
|
|
26
26
|
audio: Audio.Encoder;
|
|
27
27
|
video: Video.Root;
|
|
28
28
|
location: Location.Root;
|
package/element.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as Moq from "@moq/lite";
|
|
2
2
|
import { Broadcast } from "./broadcast";
|
|
3
3
|
import * as Source from "./source";
|
|
4
|
-
declare const OBSERVED: readonly ["url", "name", "
|
|
4
|
+
declare const OBSERVED: readonly ["url", "name", "muted", "invisible", "source"];
|
|
5
5
|
type Observed = (typeof OBSERVED)[number];
|
|
6
6
|
type SourceType = "camera" | "screen" | "file";
|
|
7
7
|
export default class MoqPublish extends HTMLElement {
|
|
8
8
|
#private;
|
|
9
|
-
static observedAttributes: readonly ["url", "name", "
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
static observedAttributes: readonly ["url", "name", "muted", "invisible", "source"];
|
|
10
|
+
state: {
|
|
11
|
+
source: Moq.Signals.Signal<File | SourceType | undefined>;
|
|
12
|
+
muted: Moq.Signals.Signal<boolean>;
|
|
13
|
+
invisible: Moq.Signals.Signal<boolean>;
|
|
14
|
+
};
|
|
15
15
|
connection: Moq.Connection.Reload;
|
|
16
16
|
broadcast: Broadcast;
|
|
17
17
|
video: Moq.Signals.Signal<Source.Camera | Source.Screen | undefined>;
|
|
@@ -22,6 +22,16 @@ export default class MoqPublish extends HTMLElement {
|
|
|
22
22
|
connectedCallback(): void;
|
|
23
23
|
disconnectedCallback(): void;
|
|
24
24
|
attributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null): void;
|
|
25
|
+
get url(): URL | undefined;
|
|
26
|
+
set url(value: string | URL | undefined);
|
|
27
|
+
get name(): Moq.Path.Valid | undefined;
|
|
28
|
+
set name(value: string | Moq.Path.Valid | undefined);
|
|
29
|
+
get source(): SourceType | File | undefined;
|
|
30
|
+
set source(value: SourceType | File | undefined);
|
|
31
|
+
get muted(): boolean;
|
|
32
|
+
set muted(value: boolean);
|
|
33
|
+
get invisible(): boolean;
|
|
34
|
+
set invisible(value: boolean);
|
|
25
35
|
}
|
|
26
36
|
declare global {
|
|
27
37
|
interface HTMLElementTagNameMap {
|
package/element.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,QAAA,MAAM,QAAQ,0DAA2D,CAAC;AAC1E,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,KAAK,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAO/C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;;IAClD,MAAM,CAAC,kBAAkB,2DAAY;IAIrC,KAAK;;;;MAIH;IAEF,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC;IAIrB,KAAK,gEAAoE;IACzE,KAAK,oEAAwE;IAC7E,IAAI,8CAAkD;IAUtD,OAAO,qBAAgB;;IAuEvB,iBAAiB;IAIjB,oBAAoB;IAIpB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAmGzF,IAAI,GAAG,IAAI,GAAG,GAAG,SAAS,CAEzB;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,EAEtC;IAED,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAErC;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,EAElD;IAED,IAAI,MAAM,IAAI,UAAU,GAAG,IAAI,GAAG,SAAS,CAE1C;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EAE9C;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAEvB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;CACD;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,aAAa,EAAE,UAAU,CAAC;KAC1B;CACD"}
|
package/element.js
CHANGED
|
@@ -1,141 +1,170 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { Signal as
|
|
3
|
-
import { B as
|
|
4
|
-
const
|
|
5
|
-
class
|
|
6
|
-
static observedAttributes =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import * as c from "@moq/lite";
|
|
2
|
+
import { Signal as o, Effect as u } from "@moq/signals";
|
|
3
|
+
import { B as d, C as h, M as b, S as v, F as g } from "./screen-BZp2qFyj.js";
|
|
4
|
+
const m = ["url", "name", "muted", "invisible", "source"], p = new FinalizationRegistry((l) => l.close());
|
|
5
|
+
class w extends HTMLElement {
|
|
6
|
+
static observedAttributes = m;
|
|
7
|
+
// Reactive state for element properties that are also HTML attributes.
|
|
8
|
+
// Access these Signals directly for reactive subscriptions (e.g. effect.get(el.state.source)).
|
|
9
|
+
state = {
|
|
10
|
+
source: new o(void 0),
|
|
11
|
+
muted: new o(!1),
|
|
12
|
+
invisible: new o(!1)
|
|
13
|
+
};
|
|
13
14
|
connection;
|
|
14
15
|
broadcast;
|
|
15
|
-
#
|
|
16
|
-
video = new
|
|
17
|
-
audio = new
|
|
18
|
-
file = new
|
|
16
|
+
#n = new o(void 0);
|
|
17
|
+
video = new o(void 0);
|
|
18
|
+
audio = new o(void 0);
|
|
19
|
+
file = new o(void 0);
|
|
19
20
|
// The inverse of the `muted` and `invisible` signals.
|
|
20
|
-
#s;
|
|
21
21
|
#e;
|
|
22
|
-
#
|
|
22
|
+
#s;
|
|
23
|
+
#t;
|
|
23
24
|
// Set when the element is connected to the DOM.
|
|
24
|
-
#
|
|
25
|
-
signals = new
|
|
25
|
+
#i = new o(!1);
|
|
26
|
+
signals = new u();
|
|
26
27
|
constructor() {
|
|
27
|
-
super(),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}), this.broadcast = new u({
|
|
28
|
+
super(), p.register(this, this.signals), this.connection = new c.Connection.Reload({
|
|
29
|
+
enabled: this.#i
|
|
30
|
+
}), this.signals.cleanup(() => this.connection.close()), this.#e = new o(!1), this.#s = new o(!1), this.#t = new o(!1), this.signals.run((s) => {
|
|
31
|
+
const t = s.get(this.state.muted), i = s.get(this.state.invisible);
|
|
32
|
+
this.#e.set(!i), this.#s.set(!t), this.#t.set(!t || !i);
|
|
33
|
+
}), this.broadcast = new d({
|
|
34
34
|
connection: this.connection.established,
|
|
35
|
-
enabled: this.#
|
|
36
|
-
path: this.path,
|
|
35
|
+
enabled: this.#i,
|
|
37
36
|
audio: {
|
|
38
|
-
enabled: this.#
|
|
37
|
+
enabled: this.#s
|
|
39
38
|
},
|
|
40
39
|
video: {
|
|
41
40
|
hd: {
|
|
42
|
-
enabled: this.#
|
|
41
|
+
enabled: this.#e
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
}), this.signals.cleanup(() => this.broadcast.close());
|
|
46
|
-
const
|
|
47
|
-
this.#
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
const
|
|
53
|
-
if (!
|
|
54
|
-
|
|
45
|
+
const e = () => {
|
|
46
|
+
this.#n.set(this.querySelector("video"));
|
|
47
|
+
}, n = new MutationObserver(e);
|
|
48
|
+
n.observe(this, { childList: !0, subtree: !0 }), this.signals.cleanup(() => n.disconnect()), e(), this.signals.run((s) => {
|
|
49
|
+
const t = s.get(this.#n);
|
|
50
|
+
if (!t) return;
|
|
51
|
+
const i = s.get(this.broadcast.video.source);
|
|
52
|
+
if (!i) {
|
|
53
|
+
t.style.display = "none";
|
|
55
54
|
return;
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
t.srcObject = new MediaStream([i]), t.style.display = "block", s.cleanup(() => {
|
|
57
|
+
t.srcObject = null;
|
|
59
58
|
});
|
|
60
|
-
}), this.signals.run(this.#
|
|
59
|
+
}), this.signals.run(this.#o.bind(this));
|
|
61
60
|
}
|
|
62
61
|
connectedCallback() {
|
|
63
|
-
this.#
|
|
62
|
+
this.#i.set(!0);
|
|
64
63
|
}
|
|
65
64
|
disconnectedCallback() {
|
|
66
|
-
this.#
|
|
65
|
+
this.#i.set(!1);
|
|
67
66
|
}
|
|
68
|
-
attributeChangedCallback(
|
|
69
|
-
if (
|
|
70
|
-
if (
|
|
71
|
-
this.url.set(s ? new URL(s) : void 0);
|
|
72
|
-
else if (
|
|
73
|
-
this.
|
|
74
|
-
else if (
|
|
67
|
+
attributeChangedCallback(e, n, s) {
|
|
68
|
+
if (n !== s)
|
|
69
|
+
if (e === "url")
|
|
70
|
+
this.connection.url.set(s ? new URL(s) : void 0);
|
|
71
|
+
else if (e === "name")
|
|
72
|
+
this.broadcast.name.set(s ? c.Path.from(s) : void 0);
|
|
73
|
+
else if (e === "source")
|
|
75
74
|
if (s === "camera" || s === "screen" || s === "file" || s === null)
|
|
76
|
-
this.source.set(s);
|
|
75
|
+
this.state.source.set(s);
|
|
77
76
|
else
|
|
78
77
|
throw new Error(`Invalid source: ${s}`);
|
|
79
|
-
else if (
|
|
80
|
-
this.muted.set(s !== null);
|
|
81
|
-
else if (
|
|
82
|
-
this.invisible.set(s !== null);
|
|
78
|
+
else if (e === "muted")
|
|
79
|
+
this.state.muted.set(s !== null);
|
|
80
|
+
else if (e === "invisible")
|
|
81
|
+
this.state.invisible.set(s !== null);
|
|
83
82
|
else {
|
|
84
|
-
const
|
|
85
|
-
throw new Error(`Invalid attribute: ${
|
|
83
|
+
const t = e;
|
|
84
|
+
throw new Error(`Invalid attribute: ${t}`);
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
|
-
#
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
if (
|
|
92
|
-
const
|
|
87
|
+
#o(e) {
|
|
88
|
+
const n = e.get(this.state.source);
|
|
89
|
+
if (!n) return;
|
|
90
|
+
if (n === "camera") {
|
|
91
|
+
const t = new h({ enabled: this.#e });
|
|
93
92
|
this.signals.run((r) => {
|
|
94
|
-
const a = r.get(
|
|
93
|
+
const a = r.get(t.source);
|
|
95
94
|
this.broadcast.video.source.set(a);
|
|
96
95
|
});
|
|
97
|
-
const
|
|
96
|
+
const i = new b({ enabled: this.#s });
|
|
98
97
|
this.signals.run((r) => {
|
|
99
|
-
const a = r.get(
|
|
98
|
+
const a = r.get(i.source);
|
|
100
99
|
this.broadcast.audio.source.set(a);
|
|
101
|
-
}),
|
|
102
|
-
|
|
100
|
+
}), e.set(this.video, t), e.set(this.audio, i), e.cleanup(() => {
|
|
101
|
+
t.close(), i.close();
|
|
103
102
|
});
|
|
104
103
|
return;
|
|
105
104
|
}
|
|
106
|
-
if (
|
|
107
|
-
const
|
|
108
|
-
enabled: this.#
|
|
105
|
+
if (n === "screen") {
|
|
106
|
+
const t = new v({
|
|
107
|
+
enabled: this.#t
|
|
109
108
|
});
|
|
110
|
-
this.signals.run((
|
|
111
|
-
const r =
|
|
112
|
-
r && (
|
|
113
|
-
}),
|
|
114
|
-
|
|
109
|
+
this.signals.run((i) => {
|
|
110
|
+
const r = i.get(t.source);
|
|
111
|
+
r && (i.set(this.broadcast.video.source, r.video), i.set(this.broadcast.audio.source, r.audio));
|
|
112
|
+
}), e.set(this.video, t), e.set(this.audio, t), e.cleanup(() => {
|
|
113
|
+
t.close();
|
|
115
114
|
});
|
|
116
115
|
return;
|
|
117
116
|
}
|
|
118
|
-
if (
|
|
119
|
-
const
|
|
117
|
+
if (n === "file" || n instanceof File) {
|
|
118
|
+
const t = new g({
|
|
120
119
|
// If a File is provided, use it directly.
|
|
121
120
|
// TODO: Show a file picker otherwise.
|
|
122
|
-
file:
|
|
123
|
-
enabled: this.#
|
|
121
|
+
file: n instanceof File ? n : void 0,
|
|
122
|
+
enabled: this.#t
|
|
124
123
|
});
|
|
125
|
-
this.signals.run((
|
|
126
|
-
const r =
|
|
124
|
+
this.signals.run((i) => {
|
|
125
|
+
const r = i.get(t.source);
|
|
127
126
|
this.broadcast.video.source.set(r.video), this.broadcast.audio.source.set(r.audio);
|
|
128
|
-
}),
|
|
129
|
-
|
|
127
|
+
}), e.cleanup(() => {
|
|
128
|
+
t.close();
|
|
130
129
|
});
|
|
131
130
|
return;
|
|
132
131
|
}
|
|
133
|
-
const s =
|
|
132
|
+
const s = n;
|
|
134
133
|
throw new Error(`Invalid source: ${s}`);
|
|
135
134
|
}
|
|
135
|
+
get url() {
|
|
136
|
+
return this.connection.url.peek();
|
|
137
|
+
}
|
|
138
|
+
set url(e) {
|
|
139
|
+
this.connection.url.set(e ? new URL(e) : void 0);
|
|
140
|
+
}
|
|
141
|
+
get name() {
|
|
142
|
+
return this.broadcast.name.peek();
|
|
143
|
+
}
|
|
144
|
+
set name(e) {
|
|
145
|
+
this.broadcast.name.set(e ? c.Path.from(e) : void 0);
|
|
146
|
+
}
|
|
147
|
+
get source() {
|
|
148
|
+
return this.state.source.peek();
|
|
149
|
+
}
|
|
150
|
+
set source(e) {
|
|
151
|
+
this.state.source.set(e);
|
|
152
|
+
}
|
|
153
|
+
get muted() {
|
|
154
|
+
return this.state.muted.peek();
|
|
155
|
+
}
|
|
156
|
+
set muted(e) {
|
|
157
|
+
this.state.muted.set(e);
|
|
158
|
+
}
|
|
159
|
+
get invisible() {
|
|
160
|
+
return this.state.invisible.peek();
|
|
161
|
+
}
|
|
162
|
+
set invisible(e) {
|
|
163
|
+
this.state.invisible.set(e);
|
|
164
|
+
}
|
|
136
165
|
}
|
|
137
|
-
customElements.define("moq-publish",
|
|
166
|
+
customElements.define("moq-publish", w);
|
|
138
167
|
export {
|
|
139
|
-
|
|
168
|
+
w as default
|
|
140
169
|
};
|
|
141
170
|
//# sourceMappingURL=element.js.map
|
package/element.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { Broadcast } from \"./broadcast\";\nimport * as Source from \"./source\";\n\n// TODO remove name; replaced with path\nconst OBSERVED = [\"url\", \"name\", \"path\", \"muted\", \"invisible\", \"source\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\ntype SourceType = \"camera\" | \"screen\" | \"file\";\n\n// Close everything when this element is garbage collected.\n// This is primarily to avoid a console.warn that we didn't close() before GC.\n// There's no destructor for web components so this is the best we can do.\nconst cleanup = new FinalizationRegistry<Effect>((signals) => signals.close());\n\nexport default class MoqPublish extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\turl = new Signal<URL | undefined>(undefined);\n\tpath = new Signal<Moq.Path.Valid | undefined>(undefined);\n\tsource = new Signal<SourceType | File | undefined>(undefined);\n\n\t// Controls whether audio/video is enabled.\n\tmuted = new Signal(false);\n\tinvisible = new Signal(false);\n\n\tconnection: Moq.Connection.Reload;\n\tbroadcast: Broadcast;\n\n\t#preview = new Signal<HTMLVideoElement | undefined>(undefined);\n\n\tvideo = new Signal<Source.Camera | Source.Screen | undefined>(undefined);\n\taudio = new Signal<Source.Microphone | Source.Screen | undefined>(undefined);\n\tfile = new Signal<Source.File | undefined>(undefined);\n\n\t// The inverse of the `muted` and `invisible` signals.\n\t#videoEnabled: Signal<boolean>;\n\t#audioEnabled: Signal<boolean>;\n\t#eitherEnabled: Signal<boolean>;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\n\tsignals = new Effect();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tcleanup.register(this, this.signals);\n\n\t\tthis.connection = new Moq.Connection.Reload({\n\t\t\turl: this.url,\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.connection.close());\n\n\t\t// The inverse of the `muted` and `invisible` signals.\n\t\t// TODO make this.signals.computed to simplify the code.\n\t\tthis.#videoEnabled = new Signal(false);\n\t\tthis.#audioEnabled = new Signal(false);\n\t\tthis.#eitherEnabled = new Signal(false);\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.muted);\n\t\t\tconst invisible = effect.get(this.invisible);\n\t\t\tthis.#videoEnabled.set(!invisible);\n\t\t\tthis.#audioEnabled.set(!muted);\n\t\t\tthis.#eitherEnabled.set(!muted || !invisible);\n\t\t});\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tenabled: this.#enabled,\n\t\t\tpath: this.path,\n\n\t\t\taudio: {\n\t\t\t\tenabled: this.#audioEnabled,\n\t\t\t},\n\t\t\tvideo: {\n\t\t\t\thd: {\n\t\t\t\t\tenabled: this.#videoEnabled,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Watch to see if the preview element is added or removed.\n\t\tconst setPreview = () => {\n\t\t\tthis.#preview.set(this.querySelector(\"video\") as HTMLVideoElement | undefined);\n\t\t};\n\t\tconst observer = new MutationObserver(setPreview);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetPreview();\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst preview = effect.get(this.#preview);\n\t\t\tif (!preview) return;\n\n\t\t\tconst source = effect.get(this.broadcast.video.source);\n\t\t\tif (!source) {\n\t\t\t\tpreview.style.display = \"none\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpreview.srcObject = new MediaStream([source]);\n\t\t\tpreview.style.display = \"block\";\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tpreview.srcObject = null;\n\t\t\t});\n\t\t});\n\n\t\tthis.signals.run(this.#runSource.bind(this));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#enabled.set(false);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) return;\n\n\t\tif (name === \"url\") {\n\t\t\tthis.url.set(newValue ? new URL(newValue) : undefined);\n\t\t} else if (name === \"name\" || name === \"path\") {\n\t\t\tthis.path.set(newValue ? Moq.Path.from(newValue) : undefined);\n\t\t} else if (name === \"source\") {\n\t\t\tif (newValue === \"camera\" || newValue === \"screen\" || newValue === \"file\" || newValue === null) {\n\t\t\t\tthis.source.set(newValue as SourceType | undefined);\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid source: ${newValue}`);\n\t\t\t}\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.muted.set(newValue !== null);\n\t\t} else if (name === \"invisible\") {\n\t\t\tthis.invisible.set(newValue !== null);\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\t#runSource(effect: Effect) {\n\t\tconst source = effect.get(this.source);\n\t\tif (!source) return;\n\n\t\tif (source === \"camera\") {\n\t\t\tconst video = new Source.Camera({ enabled: this.#videoEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(video.source);\n\t\t\t\tthis.broadcast.video.source.set(source);\n\t\t\t});\n\n\t\t\tconst audio = new Source.Microphone({ enabled: this.#audioEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(audio.source);\n\t\t\t\tthis.broadcast.audio.source.set(source);\n\t\t\t});\n\n\t\t\teffect.set(this.video, video);\n\t\t\teffect.set(this.audio, audio);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tvideo.close();\n\t\t\t\taudio.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"screen\") {\n\t\t\tconst screen = new Source.Screen({\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(screen.source);\n\t\t\t\tif (!source) return;\n\n\t\t\t\teffect.set(this.broadcast.video.source, source.video);\n\t\t\t\teffect.set(this.broadcast.audio.source, source.audio);\n\t\t\t});\n\n\t\t\teffect.set(this.video, screen);\n\t\t\teffect.set(this.audio, screen);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tscreen.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"file\" || source instanceof File) {\n\t\t\tconst fileSource = new Source.File({\n\t\t\t\t// If a File is provided, use it directly.\n\t\t\t\t// TODO: Show a file picker otherwise.\n\t\t\t\tfile: source instanceof File ? source : undefined,\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(fileSource.source);\n\t\t\t\tthis.broadcast.video.source.set(source.video);\n\t\t\t\tthis.broadcast.audio.source.set(source.audio);\n\t\t\t});\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tfileSource.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst exhaustive: never = source;\n\t\tthrow new Error(`Invalid source: ${exhaustive}`);\n\t}\n}\n\ncustomElements.define(\"moq-publish\", MoqPublish);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-publish\": MoqPublish;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqPublish","Signal","#preview","#videoEnabled","#audioEnabled","#eitherEnabled","#enabled","Effect","Moq","effect","muted","invisible","Broadcast","setPreview","observer","preview","source","#runSource","name","oldValue","newValue","exhaustive","video","Source.Camera","audio","Source.Microphone","screen","Source.Screen","fileSource","Source.File"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { Broadcast } from \"./broadcast\";\nimport * as Source from \"./source\";\n\nconst OBSERVED = [\"url\", \"name\", \"muted\", \"invisible\", \"source\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\ntype SourceType = \"camera\" | \"screen\" | \"file\";\n\n// Close everything when this element is garbage collected.\n// This is primarily to avoid a console.warn that we didn't close() before GC.\n// There's no destructor for web components so this is the best we can do.\nconst cleanup = new FinalizationRegistry<Effect>((signals) => signals.close());\n\nexport default class MoqPublish extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\t// Reactive state for element properties that are also HTML attributes.\n\t// Access these Signals directly for reactive subscriptions (e.g. effect.get(el.state.source)).\n\tstate = {\n\t\tsource: new Signal<SourceType | File | undefined>(undefined),\n\t\tmuted: new Signal(false),\n\t\tinvisible: new Signal(false),\n\t};\n\n\tconnection: Moq.Connection.Reload;\n\tbroadcast: Broadcast;\n\n\t#preview = new Signal<HTMLVideoElement | undefined>(undefined);\n\n\tvideo = new Signal<Source.Camera | Source.Screen | undefined>(undefined);\n\taudio = new Signal<Source.Microphone | Source.Screen | undefined>(undefined);\n\tfile = new Signal<Source.File | undefined>(undefined);\n\n\t// The inverse of the `muted` and `invisible` signals.\n\t#videoEnabled: Signal<boolean>;\n\t#audioEnabled: Signal<boolean>;\n\t#eitherEnabled: Signal<boolean>;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\n\tsignals = new Effect();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tcleanup.register(this, this.signals);\n\n\t\tthis.connection = new Moq.Connection.Reload({\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.connection.close());\n\n\t\t// The inverse of the `muted` and `invisible` signals.\n\t\t// TODO make this.signals.computed to simplify the code.\n\t\tthis.#videoEnabled = new Signal(false);\n\t\tthis.#audioEnabled = new Signal(false);\n\t\tthis.#eitherEnabled = new Signal(false);\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.state.muted);\n\t\t\tconst invisible = effect.get(this.state.invisible);\n\t\t\tthis.#videoEnabled.set(!invisible);\n\t\t\tthis.#audioEnabled.set(!muted);\n\t\t\tthis.#eitherEnabled.set(!muted || !invisible);\n\t\t});\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tenabled: this.#enabled,\n\n\t\t\taudio: {\n\t\t\t\tenabled: this.#audioEnabled,\n\t\t\t},\n\t\t\tvideo: {\n\t\t\t\thd: {\n\t\t\t\t\tenabled: this.#videoEnabled,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Watch to see if the preview element is added or removed.\n\t\tconst setPreview = () => {\n\t\t\tthis.#preview.set(this.querySelector(\"video\") as HTMLVideoElement | undefined);\n\t\t};\n\t\tconst observer = new MutationObserver(setPreview);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetPreview();\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst preview = effect.get(this.#preview);\n\t\t\tif (!preview) return;\n\n\t\t\tconst source = effect.get(this.broadcast.video.source);\n\t\t\tif (!source) {\n\t\t\t\tpreview.style.display = \"none\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpreview.srcObject = new MediaStream([source]);\n\t\t\tpreview.style.display = \"block\";\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tpreview.srcObject = null;\n\t\t\t});\n\t\t});\n\n\t\tthis.signals.run(this.#runSource.bind(this));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#enabled.set(false);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) return;\n\n\t\tif (name === \"url\") {\n\t\t\tthis.connection.url.set(newValue ? new URL(newValue) : undefined);\n\t\t} else if (name === \"name\") {\n\t\t\tthis.broadcast.name.set(newValue ? Moq.Path.from(newValue) : undefined);\n\t\t} else if (name === \"source\") {\n\t\t\tif (newValue === \"camera\" || newValue === \"screen\" || newValue === \"file\" || newValue === null) {\n\t\t\t\tthis.state.source.set(newValue as SourceType | undefined);\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid source: ${newValue}`);\n\t\t\t}\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.state.muted.set(newValue !== null);\n\t\t} else if (name === \"invisible\") {\n\t\t\tthis.state.invisible.set(newValue !== null);\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\t#runSource(effect: Effect) {\n\t\tconst source = effect.get(this.state.source);\n\t\tif (!source) return;\n\n\t\tif (source === \"camera\") {\n\t\t\tconst video = new Source.Camera({ enabled: this.#videoEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(video.source);\n\t\t\t\tthis.broadcast.video.source.set(source);\n\t\t\t});\n\n\t\t\tconst audio = new Source.Microphone({ enabled: this.#audioEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(audio.source);\n\t\t\t\tthis.broadcast.audio.source.set(source);\n\t\t\t});\n\n\t\t\teffect.set(this.video, video);\n\t\t\teffect.set(this.audio, audio);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tvideo.close();\n\t\t\t\taudio.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"screen\") {\n\t\t\tconst screen = new Source.Screen({\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(screen.source);\n\t\t\t\tif (!source) return;\n\n\t\t\t\teffect.set(this.broadcast.video.source, source.video);\n\t\t\t\teffect.set(this.broadcast.audio.source, source.audio);\n\t\t\t});\n\n\t\t\teffect.set(this.video, screen);\n\t\t\teffect.set(this.audio, screen);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tscreen.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"file\" || source instanceof File) {\n\t\t\tconst fileSource = new Source.File({\n\t\t\t\t// If a File is provided, use it directly.\n\t\t\t\t// TODO: Show a file picker otherwise.\n\t\t\t\tfile: source instanceof File ? source : undefined,\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(fileSource.source);\n\t\t\t\tthis.broadcast.video.source.set(source.video);\n\t\t\t\tthis.broadcast.audio.source.set(source.audio);\n\t\t\t});\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tfileSource.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst exhaustive: never = source;\n\t\tthrow new Error(`Invalid source: ${exhaustive}`);\n\t}\n\n\tget url(): URL | undefined {\n\t\treturn this.connection.url.peek();\n\t}\n\n\tset url(value: string | URL | undefined) {\n\t\tthis.connection.url.set(value ? new URL(value) : undefined);\n\t}\n\n\tget name(): Moq.Path.Valid | undefined {\n\t\treturn this.broadcast.name.peek();\n\t}\n\n\tset name(value: string | Moq.Path.Valid | undefined) {\n\t\tthis.broadcast.name.set(value ? Moq.Path.from(value) : undefined);\n\t}\n\n\tget source(): SourceType | File | undefined {\n\t\treturn this.state.source.peek();\n\t}\n\n\tset source(value: SourceType | File | undefined) {\n\t\tthis.state.source.set(value);\n\t}\n\n\tget muted(): boolean {\n\t\treturn this.state.muted.peek();\n\t}\n\n\tset muted(value: boolean) {\n\t\tthis.state.muted.set(value);\n\t}\n\n\tget invisible(): boolean {\n\t\treturn this.state.invisible.peek();\n\t}\n\n\tset invisible(value: boolean) {\n\t\tthis.state.invisible.set(value);\n\t}\n}\n\ncustomElements.define(\"moq-publish\", MoqPublish);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-publish\": MoqPublish;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqPublish","Signal","#preview","#videoEnabled","#audioEnabled","#eitherEnabled","#enabled","Effect","Moq","effect","muted","invisible","Broadcast","setPreview","observer","preview","source","#runSource","name","oldValue","newValue","exhaustive","video","Source.Camera","audio","Source.Microphone","screen","Source.Screen","fileSource","Source.File","value"],"mappings":";;;AAKA,MAAMA,IAAW,CAAC,OAAO,QAAQ,SAAS,aAAa,QAAQ,GAQzDC,IAAU,IAAI,qBAA6B,CAACC,MAAYA,EAAQ,OAAO;AAE7E,MAAqBC,UAAmB,YAAY;AAAA,EACnD,OAAO,qBAAqBH;AAAA;AAAA;AAAA,EAI5B,QAAQ;AAAA,IACP,QAAQ,IAAII,EAAsC,MAAS;AAAA,IAC3D,OAAO,IAAIA,EAAO,EAAK;AAAA,IACvB,WAAW,IAAIA,EAAO,EAAK;AAAA,EAAA;AAAA,EAG5B;AAAA,EACA;AAAA,EAEAC,KAAW,IAAID,EAAqC,MAAS;AAAA,EAE7D,QAAQ,IAAIA,EAAkD,MAAS;AAAA,EACvE,QAAQ,IAAIA,EAAsD,MAAS;AAAA,EAC3E,OAAO,IAAIA,EAAgC,MAAS;AAAA;AAAA,EAGpDE;AAAA,EACAC;AAAA,EACAC;AAAA;AAAA,EAGAC,KAAW,IAAIL,EAAO,EAAK;AAAA,EAE3B,UAAU,IAAIM,EAAA;AAAA,EAEd,cAAc;AACb,UAAA,GAEAT,EAAQ,SAAS,MAAM,KAAK,OAAO,GAEnC,KAAK,aAAa,IAAIU,EAAI,WAAW,OAAO;AAAA,MAC3C,SAAS,KAAKF;AAAA,IAAA,CACd,GACD,KAAK,QAAQ,QAAQ,MAAM,KAAK,WAAW,OAAO,GAIlD,KAAKH,KAAgB,IAAIF,EAAO,EAAK,GACrC,KAAKG,KAAgB,IAAIH,EAAO,EAAK,GACrC,KAAKI,KAAiB,IAAIJ,EAAO,EAAK,GAEtC,KAAK,QAAQ,IAAI,CAACQ,MAAW;AAC5B,YAAMC,IAAQD,EAAO,IAAI,KAAK,MAAM,KAAK,GACnCE,IAAYF,EAAO,IAAI,KAAK,MAAM,SAAS;AACjD,WAAKN,GAAc,IAAI,CAACQ,CAAS,GACjC,KAAKP,GAAc,IAAI,CAACM,CAAK,GAC7B,KAAKL,GAAe,IAAI,CAACK,KAAS,CAACC,CAAS;AAAA,IAC7C,CAAC,GAED,KAAK,YAAY,IAAIC,EAAU;AAAA,MAC9B,YAAY,KAAK,WAAW;AAAA,MAC5B,SAAS,KAAKN;AAAA,MAEd,OAAO;AAAA,QACN,SAAS,KAAKF;AAAA,MAAA;AAAA,MAEf,OAAO;AAAA,QACN,IAAI;AAAA,UACH,SAAS,KAAKD;AAAA,QAAA;AAAA,MACf;AAAA,IACD,CACA,GACD,KAAK,QAAQ,QAAQ,MAAM,KAAK,UAAU,OAAO;AAGjD,UAAMU,IAAa,MAAM;AACxB,WAAKX,GAAS,IAAI,KAAK,cAAc,OAAO,CAAiC;AAAA,IAC9E,GACMY,IAAW,IAAI,iBAAiBD,CAAU;AAChD,IAAAC,EAAS,QAAQ,MAAM,EAAE,WAAW,IAAM,SAAS,IAAM,GACzD,KAAK,QAAQ,QAAQ,MAAMA,EAAS,YAAY,GAChDD,EAAA,GAEA,KAAK,QAAQ,IAAI,CAACJ,MAAW;AAC5B,YAAMM,IAAUN,EAAO,IAAI,KAAKP,EAAQ;AACxC,UAAI,CAACa,EAAS;AAEd,YAAMC,IAASP,EAAO,IAAI,KAAK,UAAU,MAAM,MAAM;AACrD,UAAI,CAACO,GAAQ;AACZ,QAAAD,EAAQ,MAAM,UAAU;AACxB;AAAA,MACD;AAEA,MAAAA,EAAQ,YAAY,IAAI,YAAY,CAACC,CAAM,CAAC,GAC5CD,EAAQ,MAAM,UAAU,SAExBN,EAAO,QAAQ,MAAM;AACpB,QAAAM,EAAQ,YAAY;AAAA,MACrB,CAAC;AAAA,IACF,CAAC,GAED,KAAK,QAAQ,IAAI,KAAKE,GAAW,KAAK,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEA,oBAAoB;AACnB,SAAKX,GAAS,IAAI,EAAI;AAAA,EACvB;AAAA,EAEA,uBAAuB;AACtB,SAAKA,GAAS,IAAI,EAAK;AAAA,EACxB;AAAA,EAEA,yBAAyBY,GAAgBC,GAAyBC,GAAyB;AAC1F,QAAID,MAAaC;AAEjB,UAAIF,MAAS;AACZ,aAAK,WAAW,IAAI,IAAIE,IAAW,IAAI,IAAIA,CAAQ,IAAI,MAAS;AAAA,eACtDF,MAAS;AACnB,aAAK,UAAU,KAAK,IAAIE,IAAWZ,EAAI,KAAK,KAAKY,CAAQ,IAAI,MAAS;AAAA,eAC5DF,MAAS;AACnB,YAAIE,MAAa,YAAYA,MAAa,YAAYA,MAAa,UAAUA,MAAa;AACzF,eAAK,MAAM,OAAO,IAAIA,CAAkC;AAAA;AAExD,gBAAM,IAAI,MAAM,mBAAmBA,CAAQ,EAAE;AAAA,eAEpCF,MAAS;AACnB,aAAK,MAAM,MAAM,IAAIE,MAAa,IAAI;AAAA,eAC5BF,MAAS;AACnB,aAAK,MAAM,UAAU,IAAIE,MAAa,IAAI;AAAA,WACpC;AACN,cAAMC,IAAoBH;AAC1B,cAAM,IAAI,MAAM,sBAAsBG,CAAU,EAAE;AAAA,MACnD;AAAA,EACD;AAAA,EAEAJ,GAAWR,GAAgB;AAC1B,UAAMO,IAASP,EAAO,IAAI,KAAK,MAAM,MAAM;AAC3C,QAAI,CAACO,EAAQ;AAEb,QAAIA,MAAW,UAAU;AACxB,YAAMM,IAAQ,IAAIC,EAAc,EAAE,SAAS,KAAKpB,IAAe;AAC/D,WAAK,QAAQ,IAAI,CAACM,MAAW;AAC5B,cAAMO,IAASP,EAAO,IAAIa,EAAM,MAAM;AACtC,aAAK,UAAU,MAAM,OAAO,IAAIN,CAAM;AAAA,MACvC,CAAC;AAED,YAAMQ,IAAQ,IAAIC,EAAkB,EAAE,SAAS,KAAKrB,IAAe;AACnE,WAAK,QAAQ,IAAI,CAACK,MAAW;AAC5B,cAAMO,IAASP,EAAO,IAAIe,EAAM,MAAM;AACtC,aAAK,UAAU,MAAM,OAAO,IAAIR,CAAM;AAAA,MACvC,CAAC,GAEDP,EAAO,IAAI,KAAK,OAAOa,CAAK,GAC5Bb,EAAO,IAAI,KAAK,OAAOe,CAAK,GAE5Bf,EAAO,QAAQ,MAAM;AACpB,QAAAa,EAAM,MAAA,GACNE,EAAM,MAAA;AAAA,MACP,CAAC;AAED;AAAA,IACD;AAEA,QAAIR,MAAW,UAAU;AACxB,YAAMU,IAAS,IAAIC,EAAc;AAAA,QAChC,SAAS,KAAKtB;AAAA,MAAA,CACd;AAED,WAAK,QAAQ,IAAI,CAACI,MAAW;AAC5B,cAAMO,IAASP,EAAO,IAAIiB,EAAO,MAAM;AACvC,QAAKV,MAELP,EAAO,IAAI,KAAK,UAAU,MAAM,QAAQO,EAAO,KAAK,GACpDP,EAAO,IAAI,KAAK,UAAU,MAAM,QAAQO,EAAO,KAAK;AAAA,MACrD,CAAC,GAEDP,EAAO,IAAI,KAAK,OAAOiB,CAAM,GAC7BjB,EAAO,IAAI,KAAK,OAAOiB,CAAM,GAE7BjB,EAAO,QAAQ,MAAM;AACpB,QAAAiB,EAAO,MAAA;AAAA,MACR,CAAC;AAED;AAAA,IACD;AAEA,QAAIV,MAAW,UAAUA,aAAkB,MAAM;AAChD,YAAMY,IAAa,IAAIC,EAAY;AAAA;AAAA;AAAA,QAGlC,MAAMb,aAAkB,OAAOA,IAAS;AAAA,QACxC,SAAS,KAAKX;AAAA,MAAA,CACd;AAED,WAAK,QAAQ,IAAI,CAACI,MAAW;AAC5B,cAAMO,IAASP,EAAO,IAAImB,EAAW,MAAM;AAC3C,aAAK,UAAU,MAAM,OAAO,IAAIZ,EAAO,KAAK,GAC5C,KAAK,UAAU,MAAM,OAAO,IAAIA,EAAO,KAAK;AAAA,MAC7C,CAAC,GAEDP,EAAO,QAAQ,MAAM;AACpB,QAAAmB,EAAW,MAAA;AAAA,MACZ,CAAC;AAED;AAAA,IACD;AAEA,UAAMP,IAAoBL;AAC1B,UAAM,IAAI,MAAM,mBAAmBK,CAAU,EAAE;AAAA,EAChD;AAAA,EAEA,IAAI,MAAuB;AAC1B,WAAO,KAAK,WAAW,IAAI,KAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,IAAIS,GAAiC;AACxC,SAAK,WAAW,IAAI,IAAIA,IAAQ,IAAI,IAAIA,CAAK,IAAI,MAAS;AAAA,EAC3D;AAAA,EAEA,IAAI,OAAmC;AACtC,WAAO,KAAK,UAAU,KAAK,KAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,KAAKA,GAA4C;AACpD,SAAK,UAAU,KAAK,IAAIA,IAAQtB,EAAI,KAAK,KAAKsB,CAAK,IAAI,MAAS;AAAA,EACjE;AAAA,EAEA,IAAI,SAAwC;AAC3C,WAAO,KAAK,MAAM,OAAO,KAAA;AAAA,EAC1B;AAAA,EAEA,IAAI,OAAOA,GAAsC;AAChD,SAAK,MAAM,OAAO,IAAIA,CAAK;AAAA,EAC5B;AAAA,EAEA,IAAI,QAAiB;AACpB,WAAO,KAAK,MAAM,MAAM,KAAA;AAAA,EACzB;AAAA,EAEA,IAAI,MAAMA,GAAgB;AACzB,SAAK,MAAM,MAAM,IAAIA,CAAK;AAAA,EAC3B;AAAA,EAEA,IAAI,YAAqB;AACxB,WAAO,KAAK,MAAM,UAAU,KAAA;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAUA,GAAgB;AAC7B,SAAK,MAAM,UAAU,IAAIA,CAAK;AAAA,EAC/B;AACD;AAEA,eAAe,OAAO,eAAe9B,CAAU;"}
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as e, C as o, D as a, F as r, M as t, S as s } from "./screen-
|
|
2
|
-
import { B as u, i as p, a as _, P as b, u as S, b as f } from "./screen-
|
|
1
|
+
import { E as e, C as o, D as a, F as r, M as t, S as s } from "./screen-BZp2qFyj.js";
|
|
2
|
+
import { B as u, i as p, a as _, P as b, u as S, b as f } from "./screen-BZp2qFyj.js";
|
|
3
3
|
const n = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4
4
|
__proto__: null,
|
|
5
5
|
Encoder: e
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moq/publish",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "Publish
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Publish Media over QUIC broadcasts",
|
|
6
6
|
"license": "(MIT OR Apache-2.0)",
|
|
7
7
|
"repository": "github:moq-dev/moq",
|
|
8
8
|
"exports": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@moq/hang": "^0.2.0",
|
|
37
|
-
"@moq/lite": "^0.1.
|
|
37
|
+
"@moq/lite": "^0.1.4",
|
|
38
38
|
"@moq/signals": "^0.1.3",
|
|
39
39
|
"@moq/ui-core": "^0.1.0"
|
|
40
40
|
}
|
|
@@ -6246,7 +6246,7 @@ class Xn {
|
|
|
6246
6246
|
static CATALOG_TRACK = "catalog.json";
|
|
6247
6247
|
connection;
|
|
6248
6248
|
enabled;
|
|
6249
|
-
|
|
6249
|
+
name;
|
|
6250
6250
|
audio;
|
|
6251
6251
|
video;
|
|
6252
6252
|
location;
|
|
@@ -6255,12 +6255,12 @@ class Xn {
|
|
|
6255
6255
|
user;
|
|
6256
6256
|
signals = new P();
|
|
6257
6257
|
constructor(n) {
|
|
6258
|
-
this.connection = f.from(n?.connection), this.enabled = f.from(n?.enabled ?? !1), this.
|
|
6258
|
+
this.connection = f.from(n?.connection), this.enabled = f.from(n?.enabled ?? !1), this.name = f.from(n?.name), this.audio = new dn(n?.audio), this.video = new B(n?.video), this.location = new Wn(n?.location), this.chat = new Gn(n?.chat), this.preview = new pe(n?.preview), this.user = new Kn(n?.user), this.signals.run(this.#e.bind(this));
|
|
6259
6259
|
}
|
|
6260
6260
|
#e(n) {
|
|
6261
6261
|
const t = n.getAll([this.enabled, this.connection]);
|
|
6262
6262
|
if (!t) return;
|
|
6263
|
-
const [r, s] = t, i = n.get(this.
|
|
6263
|
+
const [r, s] = t, i = n.get(this.name);
|
|
6264
6264
|
if (i === void 0) return;
|
|
6265
6265
|
const o = new ln.Broadcast();
|
|
6266
6266
|
n.cleanup(() => o.close()), s.publish(i, o), n.spawn(this.#n.bind(this, o, n));
|
|
@@ -6583,4 +6583,4 @@ export {
|
|
|
6583
6583
|
aa as i,
|
|
6584
6584
|
da as u
|
|
6585
6585
|
};
|
|
6586
|
-
//# sourceMappingURL=screen-
|
|
6586
|
+
//# sourceMappingURL=screen-BZp2qFyj.js.map
|