@mebius-io/web 0.1.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/LICENSE +21 -0
- package/README.md +354 -0
- package/dist/index.cjs +723 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +262 -0
- package/dist/index.d.ts +262 -0
- package/dist/index.global.js +33784 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +681 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mebius
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# @mebius-io/web
|
|
2
|
+
|
|
3
|
+
SDK web Mebius untuk live streaming — install, ikuti docs, hit API.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@mebius-io/web)
|
|
6
|
+
[](../../LICENSE)
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Browser modern dengan WebRTC (Chrome, Edge, Firefox, Safari terbaru).
|
|
11
|
+
- **HTTPS wajib di production.** `localhost` boleh dipakai untuk development.
|
|
12
|
+
- Node 20+ hanya untuk build tooling (bukan runtime SDK).
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
> Repo ini **private** dan belum dipublish ke npm registry / domain manapun.
|
|
17
|
+
> Metode install yang terbukti jalan adalah **tarball** (di bawah). Lihat
|
|
18
|
+
> [Distribusi private](#distribusi-private-github--tarball) untuk detail +
|
|
19
|
+
> caveat git install.
|
|
20
|
+
|
|
21
|
+
### Tarball (cara utama, paling reliable)
|
|
22
|
+
|
|
23
|
+
Maintainer membuat tarball sekali per rilis, lalu consumer install dari file:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Maintainer (di repo SDK):
|
|
27
|
+
pnpm --filter @mebius-io/web build
|
|
28
|
+
pnpm --filter @mebius-io/web pack # -> packages/web/mebius-web-0.1.0.tgz
|
|
29
|
+
|
|
30
|
+
# Consumer (di project kamu):
|
|
31
|
+
npm i ./mebius-web-0.1.0.tgz
|
|
32
|
+
# atau: pnpm add ./mebius-web-0.1.0.tgz / yarn add ./mebius-web-0.1.0.tgz
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Tarball sudah berisi `dist/` (ESM + CJS + UMD + types) dan menarik dependency
|
|
36
|
+
runtime (`hls.js`) otomatis. Tidak perlu build di sisi consumer.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const { Mebius } = require("@mebius-io/web"); // CJS — works
|
|
40
|
+
import { Mebius } from "@mebius-io/web"; // ESM — works
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Setelah package dipublish ke npm registry (opsi masa depan, npm tidak butuh
|
|
44
|
+
domain):
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm i @mebius-io/web
|
|
48
|
+
# atau: pnpm add @mebius-io/web / yarn add @mebius-io/web
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Via CDN (UMD global `Mebius`) — hanya tersedia setelah publish ke registry/CDN:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script src="https://unpkg.com/@mebius-io/web/dist/index.global.js"></script>
|
|
55
|
+
<script>
|
|
56
|
+
Mebius.Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Single-file drop-in (PHP / plain HTML, no build)
|
|
61
|
+
|
|
62
|
+
For PHP or any plain-HTML project: download ONE self-contained file and add a
|
|
63
|
+
`<script>` tag — no npm, no bundler. The scale engine is bundled in; zero
|
|
64
|
+
external deps. `Mebius` becomes a global.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<script src="mebius.min.js"></script>
|
|
68
|
+
<script>
|
|
69
|
+
Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
|
|
70
|
+
const client = Mebius.connect({ token }); // token from your backend
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
File + full PHP example: [`standalone/`](./standalone/). Raw download:
|
|
75
|
+
`https://raw.githubusercontent.com/russimobiledroidx/mebius-web-sdk/v0.1.0/packages/web/standalone/mebius.min.js`
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
### a. Auth
|
|
80
|
+
|
|
81
|
+
> Token di-mint dari **backend kamu**, JANGAN embed `appSecret` di client.
|
|
82
|
+
> Backend menukar (appId + appSecret) jadi JWT short-lived; client cuma terima
|
|
83
|
+
> string token-nya.
|
|
84
|
+
|
|
85
|
+
### b. Init + connect
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { Mebius } from "@mebius-io/web";
|
|
89
|
+
|
|
90
|
+
Mebius.init({ appId: "app_123", gateway: "https://gateway.mebius.io" });
|
|
91
|
+
|
|
92
|
+
const token = await fetch("/api/mebius-token").then((r) => r.text());
|
|
93
|
+
const client = Mebius.connect({ token });
|
|
94
|
+
|
|
95
|
+
client.on("connected", () => console.log("Mebius connected"));
|
|
96
|
+
client.on("error", (err) => {
|
|
97
|
+
if (err.code === "TOKEN_EXPIRED") {
|
|
98
|
+
// refresh token dari backend, lalu connect ulang
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### c. Broadcast
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const broadcaster = client.createBroadcaster({ video: true, audio: true });
|
|
107
|
+
|
|
108
|
+
broadcaster.on("started", ({ streamId }) => console.log("live:", streamId));
|
|
109
|
+
broadcaster.on("stats", (s) => console.log(s.bitrateKbps, "kbps"));
|
|
110
|
+
|
|
111
|
+
await broadcaster.start("my-stream");
|
|
112
|
+
broadcaster.attachPreview("#preview"); // preview lokal (web convenience)
|
|
113
|
+
|
|
114
|
+
// kontrol
|
|
115
|
+
broadcaster.setMicEnabled(false);
|
|
116
|
+
broadcaster.setCameraEnabled(true);
|
|
117
|
+
await broadcaster.switchCamera();
|
|
118
|
+
|
|
119
|
+
// stop
|
|
120
|
+
await broadcaster.stop();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### d. Watch
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
const player = client.createPlayer({ mode: "low-latency" }); // atau "scale"
|
|
127
|
+
|
|
128
|
+
player.on("playing", ({ streamId }) => console.log("playing", streamId));
|
|
129
|
+
player.on("buffering", () => console.log("buffering..."));
|
|
130
|
+
player.on("ended", () => console.log("ended"));
|
|
131
|
+
|
|
132
|
+
await player.play("my-stream", "#viewer"); // <video id="viewer">
|
|
133
|
+
player.setVolume(0.8);
|
|
134
|
+
|
|
135
|
+
await player.stop();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Ganti mode kapan saja dengan membuat player baru: `mode: "low-latency"` untuk
|
|
139
|
+
delay minimum, `mode: "scale"` untuk audiens besar.
|
|
140
|
+
|
|
141
|
+
## Integrasi per framework
|
|
142
|
+
|
|
143
|
+
### Vanilla JS
|
|
144
|
+
|
|
145
|
+
ESM:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { Mebius } from "@mebius-io/web";
|
|
149
|
+
Mebius.init({ appId, gateway });
|
|
150
|
+
const client = Mebius.connect({ token });
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
UMD `<script>`:
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<script src="https://unpkg.com/@mebius-io/web/dist/index.global.js"></script>
|
|
157
|
+
<script>
|
|
158
|
+
const { Mebius } = window.Mebius;
|
|
159
|
+
Mebius.init({ appId, gateway });
|
|
160
|
+
</script>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### React
|
|
164
|
+
|
|
165
|
+
Pakai `@mebius-io/react` (hooks tipis di atas package ini):
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import { useMebius, usePlayer } from "@mebius-io/react";
|
|
169
|
+
|
|
170
|
+
function Watch({ token, streamId }) {
|
|
171
|
+
const { client } = useMebius({ appId, gateway, token });
|
|
172
|
+
const { videoRef, play } = usePlayer(client, { mode: "low-latency" });
|
|
173
|
+
return <video ref={videoRef} onClick={() => play(streamId)} autoPlay />;
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Next.js
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
"use client";
|
|
181
|
+
import dynamic from "next/dynamic";
|
|
182
|
+
// SDK butuh WebRTC browser → jangan render di server.
|
|
183
|
+
const Watch = dynamic(() => import("../components/Watch"), { ssr: false });
|
|
184
|
+
export default function Page() {
|
|
185
|
+
return <Watch />;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Vue 3 (Composition API)
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { onMounted, onUnmounted, ref } from "vue";
|
|
193
|
+
import { Mebius } from "@mebius-io/web";
|
|
194
|
+
|
|
195
|
+
export function useWatch(streamId: string) {
|
|
196
|
+
const video = ref<HTMLVideoElement>();
|
|
197
|
+
let player: ReturnType<ReturnType<typeof Mebius.connect>["createPlayer"]>;
|
|
198
|
+
onMounted(async () => {
|
|
199
|
+
Mebius.init({ appId, gateway });
|
|
200
|
+
const client = Mebius.connect({ token: await getToken() });
|
|
201
|
+
player = client.createPlayer({ mode: "low-latency" });
|
|
202
|
+
await player.play(streamId, video.value!);
|
|
203
|
+
});
|
|
204
|
+
onUnmounted(() => player?.stop());
|
|
205
|
+
return { video };
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Vite
|
|
210
|
+
|
|
211
|
+
Tidak ada config khusus. ESM langsung jalan; `hls.js` di-load lazy hanya saat
|
|
212
|
+
mode `"scale"` dipakai, jadi tidak menambah bundle low-latency.
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
| Class | Method | Return | Keterangan |
|
|
217
|
+
|---|---|---|---|
|
|
218
|
+
| `Mebius` | `init({ appId, gateway })` | `void` | Konfigurasi sekali di awal. |
|
|
219
|
+
| `Mebius` | `connect({ token })` | `MebiusClient` | Buka koneksi. |
|
|
220
|
+
| `MebiusClient` | `createBroadcaster({ video?, audio? })` | `MebiusBroadcaster` | |
|
|
221
|
+
| `MebiusClient` | `createPlayer({ mode })` | `MebiusPlayer` | `mode: "low-latency" \| "scale"` |
|
|
222
|
+
| `MebiusClient` | `disconnect(reason?)` | `void` | |
|
|
223
|
+
| `MebiusBroadcaster` | `start(streamId)` | `Promise<void>` | |
|
|
224
|
+
| `MebiusBroadcaster` | `stop()` | `Promise<void>` | |
|
|
225
|
+
| `MebiusBroadcaster` | `switchCamera()` | `Promise<void>` | |
|
|
226
|
+
| `MebiusBroadcaster` | `setMicEnabled(bool)` | `void` | |
|
|
227
|
+
| `MebiusBroadcaster` | `setCameraEnabled(bool)` | `void` | |
|
|
228
|
+
| `MebiusBroadcaster` | `attachPreview(target)` | `void` | Preview lokal (web). |
|
|
229
|
+
| `MebiusPlayer` | `play(streamId, viewTarget)` | `Promise<void>` | `viewTarget`: `<video>` atau selector. |
|
|
230
|
+
| `MebiusPlayer` | `stop()` | `Promise<void>` | |
|
|
231
|
+
| `MebiusPlayer` | `setVolume(0..1)` | `void` | |
|
|
232
|
+
|
|
233
|
+
### Events
|
|
234
|
+
|
|
235
|
+
| Emitter | Event | Payload |
|
|
236
|
+
|---|---|---|
|
|
237
|
+
| client | `connected` | — |
|
|
238
|
+
| client | `disconnected` | `{ reason? }` |
|
|
239
|
+
| client | `error` | `MebiusError` |
|
|
240
|
+
| broadcaster | `started` | `{ streamId }` |
|
|
241
|
+
| broadcaster | `stopped` | — |
|
|
242
|
+
| broadcaster | `stats` | `{ bitrateKbps, framesPerSecond, rttMs? }` |
|
|
243
|
+
| player | `playing` | `{ streamId }` |
|
|
244
|
+
| player | `buffering` | — |
|
|
245
|
+
| player | `ended` | — |
|
|
246
|
+
| player | `stats` | `{ bitrateKbps, framesPerSecond, latencyMs? }` |
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
client.on("connected", () => {});
|
|
250
|
+
client.on("error", (e) => console.warn(e.code, e.message));
|
|
251
|
+
broadcaster.on("stats", (s) => console.log(s.bitrateKbps));
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Error handling
|
|
255
|
+
|
|
256
|
+
Semua error adalah `MebiusError` dengan `.code`:
|
|
257
|
+
|
|
258
|
+
| Code | Arti | Recover |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| `TOKEN_EXPIRED` | Token habis masa berlaku | Mint token baru di backend, connect ulang. |
|
|
261
|
+
| `PERMISSION_DENIED` | Izin kamera/mic ditolak | Minta user mengizinkan, retry `start()`. |
|
|
262
|
+
| `CONNECTION_FAILED` | Gagal konek ke gateway | Cek jaringan/gateway, retry dengan backoff. |
|
|
263
|
+
| `NOT_CONNECTED` | Dipakai sebelum `connect()` | Pastikan `connect()` sukses dulu. |
|
|
264
|
+
| `STREAM_NOT_FOUND` | Stream tidak ada | Verifikasi `streamId`. |
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
client.on("error", (e) => {
|
|
268
|
+
switch (e.code) {
|
|
269
|
+
case "TOKEN_EXPIRED": return refreshAndReconnect();
|
|
270
|
+
case "PERMISSION_DENIED": return showPermissionHelp();
|
|
271
|
+
default: console.error(e);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Troubleshooting
|
|
277
|
+
|
|
278
|
+
- **Izin kamera/mic:** browser hanya memberi izin di context aman (HTTPS atau
|
|
279
|
+
`localhost`). Pastikan halaman tidak dibuka via `file://`.
|
|
280
|
+
- **HTTPS:** WebRTC butuh secure context di production.
|
|
281
|
+
- **Autoplay:** browser memblok autoplay dengan suara. Mulai playback setelah
|
|
282
|
+
interaksi user, atau set `muted` dulu lalu unmute via `setVolume`.
|
|
283
|
+
|
|
284
|
+
## Distribusi private (GitHub / tarball)
|
|
285
|
+
|
|
286
|
+
SDK ini hidup di **monorepo private** (`russimobiledroidx/mebius-web-sdk`)
|
|
287
|
+
dengan 3 package: `@mebius-io/web` (core, tanpa dependency internal), `@mebius-io/react`,
|
|
288
|
+
`@mebius-io/react-native`. Tidak ada registry/domain publik. Berikut metode install
|
|
289
|
+
beserta tingkat keandalannya — apa adanya, tanpa janji palsu.
|
|
290
|
+
|
|
291
|
+
### ✅ Tarball — reliable (cara utama)
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# 1. Maintainer build + pack semua package sekaligus (di repo SDK):
|
|
295
|
+
pnpm pack:all
|
|
296
|
+
# -> mebius-web-0.1.0.tgz
|
|
297
|
+
# mebius-react-0.1.0.tgz
|
|
298
|
+
# mebius-react-native-0.1.0.tgz (di root repo)
|
|
299
|
+
|
|
300
|
+
# 2. Consumer install (copy .tgz ke project, lalu):
|
|
301
|
+
npm i ./mebius-web-0.1.0.tgz
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Selalu jalan untuk repo private karena tidak menyentuh registry sama sekali.
|
|
305
|
+
`@mebius-io/web` self-contained (tidak punya workspace dep), jadi paling bersih.
|
|
306
|
+
|
|
307
|
+
### ⚠️ git install — TIDAK reliable untuk monorepo subpackage
|
|
308
|
+
|
|
309
|
+
`npm i 'github:russimobiledroidx/mebius-web-sdk'` **tidak** bisa dipakai untuk
|
|
310
|
+
menginstall satu sub-package: npm/pnpm meng-clone seluruh repo dan hanya membaca
|
|
311
|
+
`package.json` di root, yang `private: true` dan bukan salah satu dari ketiga
|
|
312
|
+
package. npm juga tidak mendukung pemilihan sub-direktori untuk git dependency
|
|
313
|
+
secara native. Jadi metode ini **tidak didukung** di sini — pakai tarball.
|
|
314
|
+
|
|
315
|
+
(Catatan: tool pihak ketiga seperti `gitpkg` mem-publish subdir sebagai git URL,
|
|
316
|
+
tetapi **tidak bekerja untuk repo private**. Karena itu tarball adalah jalur
|
|
317
|
+
utama.)
|
|
318
|
+
|
|
319
|
+
### Cross-package dependency (react / react-native)
|
|
320
|
+
|
|
321
|
+
`@mebius-io/react` bergantung ke `@mebius-io/web`. Saat di-pack, pnpm menulis ulang
|
|
322
|
+
`workspace:*` menjadi versi konkret (`"@mebius-io/web": "0.1.0"`) yang tidak ada di
|
|
323
|
+
registry manapun untuk repo private ini. Akibatnya, **install tarball react
|
|
324
|
+
sendirian akan gagal** (npm mencoba mengambil `@mebius-io/web@0.1.0` dari registry).
|
|
325
|
+
|
|
326
|
+
Solusi: install kedua tarball dalam **satu perintah** supaya npm memuaskan
|
|
327
|
+
`@mebius-io/web@0.1.0` dari tarball lokal yang kamu sediakan:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm i ./mebius-web-0.1.0.tgz ./mebius-react-0.1.0.tgz react
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
`@mebius-io/web` (core) dan `@mebius-io/react-native` (skeleton, tanpa dep internal)
|
|
334
|
+
bisa di-install standalone tanpa kendala ini.
|
|
335
|
+
|
|
336
|
+
### Opsi masa depan (lebih mulus): npm publish / GitHub Packages
|
|
337
|
+
|
|
338
|
+
Tidak seperti Maven Central, **npm tidak punya syarat domain**. Begitu siap,
|
|
339
|
+
publish ke registry npm privat atau **GitHub Packages** menghapus seluruh dance
|
|
340
|
+
tarball:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
pnpm release # turbo build + changeset publish
|
|
344
|
+
# consumer cukup: npm i @mebius-io/web
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Versioning & changelog
|
|
348
|
+
|
|
349
|
+
SemVer. Public API stabil per major version; perubahan breaking pada kontrak =
|
|
350
|
+
major bump serempak di semua platform Mebius. Lihat changeset di repo.
|
|
351
|
+
|
|
352
|
+
## License
|
|
353
|
+
|
|
354
|
+
MIT
|