nixamp 0.28.1 → 0.28.2
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/dist/owner.js +2 -0
- package/dist/server.js +19 -7
- package/package.json +1 -1
- package/src/owner.ts +1 -0
- package/src/server.ts +19 -7
- package/web/dist/assets/{hls-3VKVEQE3-DQXeuMAN.js → hls-3VKVEQE3-Cw5UD-5P.js} +1 -1
- package/web/dist/assets/index-BqcDIh2Q.js +3 -0
- package/web/dist/assets/{mpegts-LO6RVLD6-tqmB8BfI.js → mpegts-LO6RVLD6-DS0PXyu3.js} +1 -1
- package/web/dist/assets/{mpegts-BRcpX4rU.js → mpegts-a5NkXKRN.js} +1 -1
- package/web/dist/index.html +4 -1
- package/web/dist/sw.js +5 -5
- package/web/dist/assets/index-HDrZHpqb.js +0 -3
package/dist/owner.js
CHANGED
|
@@ -136,6 +136,8 @@ export function needsMember(path, method = "GET") {
|
|
|
136
136
|
return true;
|
|
137
137
|
if (method === "POST" && /^\/api\/channels\/[^/]+\/keep$/.test(path))
|
|
138
138
|
return true;
|
|
139
|
+
if (method === "POST" && /^\/api\/channels\/[^/]+\/(?:start|stop|restart)$/.test(path))
|
|
140
|
+
return true;
|
|
139
141
|
// A link -- a YouTube page, an IPTV feed, a file somewhere -- is the one
|
|
140
142
|
// thing a member can go live with that needs nothing on the server first,
|
|
141
143
|
// and it was the one thing they could not. Going live with one is the same
|
package/dist/server.js
CHANGED
|
@@ -3480,14 +3480,18 @@ export function createHandler(engine, options) {
|
|
|
3480
3480
|
return;
|
|
3481
3481
|
}
|
|
3482
3482
|
if (!check.allowed) {
|
|
3483
|
-
|
|
3483
|
+
const ownedChannel = channelId === "" ? "" : options.channels?.info(channelId)?.startedBy ?? "";
|
|
3484
|
+
const memberOwnsChannel = member !== "" && ownedChannel === member;
|
|
3485
|
+
if (member !== "" && (needsMember(path, request.method ?? "GET") || memberOwnsChannel)) {
|
|
3484
3486
|
// Metered per member, before anything is done: going live is a
|
|
3485
3487
|
// decoder on this machine, and a script could ask for one a
|
|
3486
3488
|
// second. Three a minute is a person; more is not.
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3489
|
+
if (needsMember(path, request.method ?? "GET")) {
|
|
3490
|
+
const refused = await memberThrottle.handle(requestFor(request));
|
|
3491
|
+
if (refused) {
|
|
3492
|
+
await answerWith(response, refused);
|
|
3493
|
+
return;
|
|
3494
|
+
}
|
|
3491
3495
|
}
|
|
3492
3496
|
liveBy = member;
|
|
3493
3497
|
}
|
|
@@ -4406,7 +4410,7 @@ export function createHandler(engine, options) {
|
|
|
4406
4410
|
json(response, 200, { ok: true, channel: id, name });
|
|
4407
4411
|
return;
|
|
4408
4412
|
}
|
|
4409
|
-
if (action === undefined && request.method === "DELETE") {
|
|
4413
|
+
if ((action === undefined && request.method === "DELETE") || (action === "stop" && request.method === "POST")) {
|
|
4410
4414
|
// A member takes off what they put on, and nothing else.
|
|
4411
4415
|
if (liveBy && channels.info(id)?.startedBy !== liveBy) {
|
|
4412
4416
|
json(response, 403, { error: "that stream is not yours to take off" });
|
|
@@ -4444,7 +4448,7 @@ export function createHandler(engine, options) {
|
|
|
4444
4448
|
* take it off, put it back -- without having to know the source, which
|
|
4445
4449
|
* a browser is never told.
|
|
4446
4450
|
*/
|
|
4447
|
-
if (action === "restart") {
|
|
4451
|
+
if (action === "start" || action === "restart") {
|
|
4448
4452
|
if (!channels.has(id)) {
|
|
4449
4453
|
json(response, 404, { error: "nothing is playing on that channel" });
|
|
4450
4454
|
return;
|
|
@@ -4453,6 +4457,10 @@ export function createHandler(engine, options) {
|
|
|
4453
4457
|
json(response, 409, { error: "that channel is published into this server; restart it at the publisher" });
|
|
4454
4458
|
return;
|
|
4455
4459
|
}
|
|
4460
|
+
if (liveBy && channels.info(id)?.startedBy !== liveBy) {
|
|
4461
|
+
json(response, 403, { error: "that stream is not yours to restart" });
|
|
4462
|
+
return;
|
|
4463
|
+
}
|
|
4456
4464
|
const restarted = channels.restart(id);
|
|
4457
4465
|
json(response, restarted ? 200 : 409, { ok: restarted });
|
|
4458
4466
|
return;
|
|
@@ -4472,6 +4480,10 @@ export function createHandler(engine, options) {
|
|
|
4472
4480
|
// a member, counted and marked like anything else they put on.
|
|
4473
4481
|
if (liveBy) {
|
|
4474
4482
|
const info = channels.info(id);
|
|
4483
|
+
if (info && info.startedBy && info.startedBy !== liveBy) {
|
|
4484
|
+
json(response, 403, { error: "that stream is not yours to keep" });
|
|
4485
|
+
return;
|
|
4486
|
+
}
|
|
4475
4487
|
if (info && !info.startedBy && !channels.isEphemeral(id)) {
|
|
4476
4488
|
json(response, 403, { error: "that stream is the owner's" });
|
|
4477
4489
|
return;
|
package/package.json
CHANGED
package/src/owner.ts
CHANGED
|
@@ -148,6 +148,7 @@ export function needsMember(path: string, method = "GET"): boolean {
|
|
|
148
148
|
if (method === "POST" && /^\/api\/tracks\/\d+\/live$/.test(path)) return true;
|
|
149
149
|
if (method === "POST" && /^\/api\/catalogs\/[^/]+\/entries\/[^/]+\/live$/.test(path)) return true;
|
|
150
150
|
if (method === "POST" && /^\/api\/channels\/[^/]+\/keep$/.test(path)) return true;
|
|
151
|
+
if (method === "POST" && /^\/api\/channels\/[^/]+\/(?:start|stop|restart)$/.test(path)) return true;
|
|
151
152
|
// A link -- a YouTube page, an IPTV feed, a file somewhere -- is the one
|
|
152
153
|
// thing a member can go live with that needs nothing on the server first,
|
|
153
154
|
// and it was the one thing they could not. Going live with one is the same
|
package/src/server.ts
CHANGED
|
@@ -3926,14 +3926,18 @@ export function createHandler(engine: Engine, options: HandlerOptions) {
|
|
|
3926
3926
|
return;
|
|
3927
3927
|
}
|
|
3928
3928
|
if (!check.allowed) {
|
|
3929
|
-
|
|
3929
|
+
const ownedChannel = channelId === "" ? "" : options.channels?.info(channelId)?.startedBy ?? "";
|
|
3930
|
+
const memberOwnsChannel = member !== "" && ownedChannel === member;
|
|
3931
|
+
if (member !== "" && (needsMember(path, request.method ?? "GET") || memberOwnsChannel)) {
|
|
3930
3932
|
// Metered per member, before anything is done: going live is a
|
|
3931
3933
|
// decoder on this machine, and a script could ask for one a
|
|
3932
3934
|
// second. Three a minute is a person; more is not.
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3935
|
+
if (needsMember(path, request.method ?? "GET")) {
|
|
3936
|
+
const refused = await memberThrottle.handle(requestFor(request));
|
|
3937
|
+
if (refused) {
|
|
3938
|
+
await answerWith(response, refused);
|
|
3939
|
+
return;
|
|
3940
|
+
}
|
|
3937
3941
|
}
|
|
3938
3942
|
liveBy = member;
|
|
3939
3943
|
} else {
|
|
@@ -4858,7 +4862,7 @@ export function createHandler(engine: Engine, options: HandlerOptions) {
|
|
|
4858
4862
|
return;
|
|
4859
4863
|
}
|
|
4860
4864
|
|
|
4861
|
-
if (action === undefined && request.method === "DELETE") {
|
|
4865
|
+
if ((action === undefined && request.method === "DELETE") || (action === "stop" && request.method === "POST")) {
|
|
4862
4866
|
// A member takes off what they put on, and nothing else.
|
|
4863
4867
|
if (liveBy && channels.info(id)?.startedBy !== liveBy) {
|
|
4864
4868
|
json(response, 403, { error: "that stream is not yours to take off" });
|
|
@@ -4898,7 +4902,7 @@ export function createHandler(engine: Engine, options: HandlerOptions) {
|
|
|
4898
4902
|
* take it off, put it back -- without having to know the source, which
|
|
4899
4903
|
* a browser is never told.
|
|
4900
4904
|
*/
|
|
4901
|
-
if (action === "restart") {
|
|
4905
|
+
if (action === "start" || action === "restart") {
|
|
4902
4906
|
if (!channels.has(id)) {
|
|
4903
4907
|
json(response, 404, { error: "nothing is playing on that channel" });
|
|
4904
4908
|
return;
|
|
@@ -4907,6 +4911,10 @@ export function createHandler(engine: Engine, options: HandlerOptions) {
|
|
|
4907
4911
|
json(response, 409, { error: "that channel is published into this server; restart it at the publisher" });
|
|
4908
4912
|
return;
|
|
4909
4913
|
}
|
|
4914
|
+
if (liveBy && channels.info(id)?.startedBy !== liveBy) {
|
|
4915
|
+
json(response, 403, { error: "that stream is not yours to restart" });
|
|
4916
|
+
return;
|
|
4917
|
+
}
|
|
4910
4918
|
const restarted = channels.restart(id);
|
|
4911
4919
|
json(response, restarted ? 200 : 409, { ok: restarted });
|
|
4912
4920
|
return;
|
|
@@ -4927,6 +4935,10 @@ export function createHandler(engine: Engine, options: HandlerOptions) {
|
|
|
4927
4935
|
// a member, counted and marked like anything else they put on.
|
|
4928
4936
|
if (liveBy) {
|
|
4929
4937
|
const info = channels.info(id);
|
|
4938
|
+
if (info && info.startedBy && info.startedBy !== liveBy) {
|
|
4939
|
+
json(response, 403, { error: "that stream is not yours to keep" });
|
|
4940
|
+
return;
|
|
4941
|
+
}
|
|
4930
4942
|
if (info && !info.startedBy && !channels.isEphemeral(id)) {
|
|
4931
4943
|
json(response, 403, { error: "that stream is the owner's" });
|
|
4932
4944
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./index-
|
|
1
|
+
import{t as e}from"./index-BqcDIh2Q.js";var t=3;async function n(n){let{media:r,src:i,isTv:a}=n,{default:o}=await e(async()=>{let{default:e}=await import(`./hls-n74Cnh8A.js`);return{default:e}},[]);if(!o.isSupported())return n.onError(`This browser cannot play HLS streams.`),{destroy:()=>void 0,levels:()=>[]};let s=new o({...a?{maxBufferLength:60,maxMaxBufferLength:120,backBufferLength:30,liveSyncDurationCount:4}:{backBufferLength:90},enableWorker:!0}),c=0,l=!1;s.on(o.Events.ERROR,(e,r)=>{if(!l&&r.fatal){if(c>=t){n.onError(`This stream kept failing and has been stopped.`),s.destroy();return}switch(c+=1,r.type){case o.ErrorTypes.NETWORK_ERROR:n.onNotice(`Reconnecting…`),s.startLoad();break;case o.ErrorTypes.MEDIA_ERROR:n.onNotice(`Recovering…`),s.recoverMediaError();break;default:n.onError(`This stream could not be played.`),s.destroy()}}}),s.on(o.Events.MANIFEST_PARSED,()=>{l||(n.onNotice(null),n.onReady?.({live:s.levels.length>0&&!Number.isFinite(r.duration),levels:u()}))}),s.on(o.Events.LEVEL_LOADED,(e,t)=>{l||n.onReady?.({live:t.details.live,levels:u()})}),s.on(o.Events.FRAG_BUFFERED,()=>{l||n.onNotice(null)});function u(){return s.levels.map((e,t)=>({index:t,height:e.height||null,bitrate:e.bitrate||null,label:e.height?`${String(e.height)}p`:`${String(Math.round((e.bitrate||0)/1e3))}k`}))}return s.loadSource(i),s.attachMedia(r),{destroy(){l=!0,s.destroy()},levels:u,setLevel(e){s.currentLevel=e},currentLevel:()=>s.autoLevelEnabled?-1:s.currentLevel}}export{n as createHlsEngine};
|