@officebeats/matrix-iptv-cli 3.0.1 → 3.0.4

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/about.md CHANGED
@@ -1,32 +1,32 @@
1
- # Vibe IPTV CLI
2
-
3
- Learning how to vibecode with Google antigravity by building tools
4
- I casually need. Made this possible thanks to the use of Google Antigravity AI. :)
5
-
6
- I'm Ernesto "Beats", a product manager by profession.
7
-
8
- *+* ++++++++++
9
- +++ *++++++++++++++*
10
- +++++++* *+++*
11
- +++++ *++* *+++
12
- +++* +++++++++* ++*
13
- +++ ++* *+* ++
14
- +++ +++ +++ +++
15
- +++ +++* *++* +++
16
- +++ ++++* +++* *++
17
- +++ ++++++++++* +++*
18
- +++ +++ ++++
19
- +++ +++ ++++*
20
- +++ ++++++++++++++
21
- +++ +++ *+++++
22
- +++ +++
23
- +++ +++
24
- *+* *++
25
-
26
- @@@@@@ @ @ ++ ++ ++++++
27
- @@ @@ @@@@ @@@@@ @@@@@ @@ @@ @@@@ @@@@+++ +++ +
28
- @@ @@@ @@ @@ @@@ @ @@ @@ @ @ ++ + ++ + ++ ++
29
- @@ @@ @@ @@@@ @@ @@ @@ @@ @ @ ++ ++ + ++ ++
30
- @@ @@ @@@ @@@@ @@@ @ @@@ @@@ + + ++++
31
-
1
+ # Vibe IPTV CLI
2
+
3
+ Learning how to vibecode with Google antigravity by building tools
4
+ I casually need. Made this possible thanks to the use of Google Antigravity AI. :)
5
+
6
+ I'm Ernesto "Beats", a product manager by profession.
7
+
8
+ *+* ++++++++++
9
+ +++ *++++++++++++++*
10
+ +++++++* *+++*
11
+ +++++ *++* *+++
12
+ +++* +++++++++* ++*
13
+ +++ ++* *+* ++
14
+ +++ +++ +++ +++
15
+ +++ +++* *++* +++
16
+ +++ ++++* +++* *++
17
+ +++ ++++++++++* +++*
18
+ +++ +++ ++++
19
+ +++ +++ ++++*
20
+ +++ ++++++++++++++
21
+ +++ +++ *+++++
22
+ +++ +++
23
+ +++ +++
24
+ *+* *++
25
+
26
+ @@@@@@ @ @ ++ ++ ++++++
27
+ @@ @@ @@@@ @@@@@ @@@@@ @@ @@ @@@@ @@@@+++ +++ +
28
+ @@ @@@ @@ @@ @@@ @ @@ @@ @ @ ++ + ++ + ++ ++
29
+ @@ @@ @@ @@@@ @@ @@ @@ @@ @ @ ++ ++ + ++ ++
30
+ @@ @@ @@@ @@@@ @@@ @ @@@ @@@ + + ++++
31
+
32
32
  www.ProductMG.com
package/bin/cli.js CHANGED
@@ -1,32 +1,32 @@
1
1
  #!/usr/bin/env node
2
-
3
- const { spawn } = require("child_process");
4
- const path = require("path");
5
- const os = require("os");
6
- const fs = require("fs");
7
-
8
- const binaryName =
9
- os.platform() === "win32" ? "matrix-iptv.exe" : "matrix-iptv";
10
- const binaryPath = path.join(__dirname, binaryName);
11
-
12
- if (!fs.existsSync(binaryPath)) {
13
- console.error("\n❌ Matrix IPTV binary not found.");
14
- console.log(
15
- "Please try reinstalling the package: npm install -g @officebeats/matrix-iptv-cli\n"
16
- );
17
- process.exit(1);
18
- }
19
-
20
- const child = spawn(binaryPath, process.argv.slice(2), {
21
- stdio: "inherit",
22
- windowsHide: false,
23
- });
24
-
25
- child.on("error", (err) => {
26
- console.error("Failed to start Matrix IPTV:", err);
27
- process.exit(1);
28
- });
29
-
30
- child.on("exit", (code) => {
31
- process.exit(code || 0);
32
- });
2
+
3
+ const { spawn } = require("child_process");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const fs = require("fs");
7
+
8
+ const binaryName =
9
+ os.platform() === "win32" ? "matrix-iptv.exe" : "matrix-iptv";
10
+ const binaryPath = path.join(__dirname, binaryName);
11
+
12
+ if (!fs.existsSync(binaryPath)) {
13
+ console.error("\n❌ Matrix IPTV binary not found.");
14
+ console.log(
15
+ "Please try reinstalling the package: npm install -g @officebeats/matrix-iptv-cli\n"
16
+ );
17
+ process.exit(1);
18
+ }
19
+
20
+ const child = spawn(binaryPath, process.argv.slice(2), {
21
+ stdio: "inherit",
22
+ windowsHide: false,
23
+ });
24
+
25
+ child.on("error", (err) => {
26
+ console.error("Failed to start Matrix IPTV:", err);
27
+ process.exit(1);
28
+ });
29
+
30
+ child.on("exit", (code) => {
31
+ process.exit(code || 0);
32
+ });
package/index.html CHANGED
@@ -1,90 +1,128 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>IPTV CLI Web</title>
7
- <style>
8
- body {
9
- background-color: #0d0d0d;
10
- color: #ccc;
11
- font-family: 'Courier New', Courier, monospace;
12
- display: flex;
13
- justify-content: center;
14
- align-items: center;
15
- height: 100vh;
16
- overflow: hidden;
17
- margin: 0;
18
- }
19
- #terminal-container {
20
- border: 2px solid #555;
21
- padding: 10px;
22
- background: #000;
23
- box-shadow: 0 0 20px rgba(0, 255, 0, 0.1);
24
- }
25
- pre {
26
- margin: 0;
27
- font-size: 14px;
28
- line-height: 14px;
29
- }
30
- .controls {
31
- position: absolute;
32
- bottom: 10px;
33
- color: #666;
34
- font-size: 12px;
35
- }
36
- </style>
37
- </head>
38
- <body>
39
- <div id="terminal-container">
40
- <pre id="terminal-output">Loading WebAssembly...</pre>
41
- </div>
42
- <div class="controls">
43
- Use Arrow Keys or j/k to navigate. Enter to select.
44
- </div>
45
-
46
- <script type="module">
47
- // Import init function and WasmClient class
48
- // Note: The path depends on where wasm-pack outputs files. Usually ./pkg/
49
- import init, { WasmClient } from './pkg/iptv_cli.js';
50
-
51
- async function main() {
52
- try {
53
- await init();
54
- console.log("Wasm initialized");
55
-
56
- const client = new WasmClient();
57
- const termOutput = document.getElementById('terminal-output');
58
-
59
- function renderLoop() {
60
- const output = client.draw();
61
- termOutput.innerText = output;
62
- requestAnimationFrame(renderLoop);
63
- }
64
-
65
- // Initial render
66
- renderLoop();
67
-
68
- // Input handling
69
- document.addEventListener('keydown', (e) => {
70
- // Prevent default scrolling for arrow keys
71
- if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Tab"].includes(e.key)) {
72
- e.preventDefault();
73
- }
74
-
75
- // Filter out modifier keys alone
76
- if (["Shift", "Control", "Alt", "Meta"].includes(e.key)) return;
77
-
78
- client.handle_key(e.key);
79
- });
80
-
81
- } catch (err) {
82
- console.error("Failed to start Wasm:", err);
83
- document.getElementById('terminal-output').innerText = "Error loading Wasm:\n" + err;
84
- }
85
- }
86
-
87
- main();
88
- </script>
89
- </body>
90
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Matrix IPTV PWA</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
8
+ <style>
9
+ body {
10
+ background-color: #0d0208;
11
+ color: #00ff41;
12
+ font-family: "Courier New", Courier, monospace;
13
+ margin: 0;
14
+ padding: 0;
15
+ overflow: hidden;
16
+ display: flex;
17
+ flex-direction: column;
18
+ height: 100vh;
19
+ }
20
+ #terminal {
21
+ flex: 1;
22
+ white-space: pre;
23
+ padding: 5px;
24
+ font-size: 1.8vw; /* Responsive font size */
25
+ line-height: 1.1;
26
+ overflow: hidden;
27
+ border-bottom: 1px solid #003b00;
28
+ }
29
+ #video-container {
30
+ width: 100%;
31
+ background: #000;
32
+ display: none;
33
+ position: relative;
34
+ aspect-ratio: 16 / 9;
35
+ border-top: 2px solid #00ff41;
36
+ }
37
+ video {
38
+ width: 100%;
39
+ height: 100%;
40
+ }
41
+ @media (min-width: 1024px) {
42
+ #terminal {
43
+ font-size: 14px;
44
+ line-height: 16px;
45
+ }
46
+ #video-container {
47
+ position: absolute;
48
+ bottom: 20px;
49
+ right: 20px;
50
+ width: 480px;
51
+ border: 2px solid #00ff41;
52
+ }
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="terminal">Loading Matrix Interface...</div>
58
+ <div id="video-container">
59
+ <video id="video" controls playsinline></video>
60
+ </div>
61
+
62
+ <script>
63
+ // Global function for Wasm to call
64
+ window.playStream = function (url) {
65
+ console.log("[JS] Playing:", url);
66
+ const video = document.getElementById("video");
67
+ const container = document.getElementById("video-container");
68
+ container.style.display = "block";
69
+
70
+ if (Hls.isSupported()) {
71
+ const hls = new Hls();
72
+ hls.loadSource(url);
73
+ hls.attachMedia(video);
74
+ hls.on(Hls.Events.MANIFEST_PARSED, function () {
75
+ video.play();
76
+ });
77
+ } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
78
+ // Native HLS support (Safari)
79
+ video.src = url;
80
+ video.addEventListener("loadedmetadata", function () {
81
+ video.play();
82
+ });
83
+ }
84
+ };
85
+ </script>
86
+
87
+ <script type="module">
88
+ import init, { WasmClient } from "./pkg/matrix_iptv.js";
89
+
90
+ async function run() {
91
+ try {
92
+ await init();
93
+ const client = new WasmClient();
94
+ const terminal = document.getElementById("terminal");
95
+
96
+ // Render Loop
97
+ function step() {
98
+ const output = client.draw();
99
+ terminal.textContent = output;
100
+ requestAnimationFrame(step);
101
+ }
102
+ requestAnimationFrame(step);
103
+
104
+ // Input Handling
105
+ document.addEventListener("keydown", (event) => {
106
+ if (
107
+ [
108
+ "ArrowUp",
109
+ "ArrowDown",
110
+ "ArrowLeft",
111
+ "ArrowRight",
112
+ "Space",
113
+ ].includes(event.code)
114
+ ) {
115
+ event.preventDefault();
116
+ }
117
+ client.handle_key(event.key);
118
+ });
119
+ } catch (e) {
120
+ console.error("Wasm Init Failed:", e);
121
+ document.getElementById("terminal").textContent =
122
+ "CRITICAL FAILURE: WASM LOAD ERROR\n" + e;
123
+ }
124
+ }
125
+ run();
126
+ </script>
127
+ </body>
128
+ </html>
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
- {
2
- "name": "@officebeats/matrix-iptv-cli",
3
- "version": "3.0.1",
4
- "description": "The premium Terminal IPTV Decoder",
5
- "main": "index.js",
6
- "bin": {
7
- "matrix-iptv": "bin/cli.js"
8
- },
9
- "scripts": {
10
- "postinstall": "node scripts/install-binary.js"
11
- },
12
- "keywords": [
13
- "iptv",
14
- "cli",
15
- "tui",
16
- "matrix",
17
- "sports",
18
- "xtream"
19
- ],
20
- "author": "Beats",
21
- "license": "MIT",
22
- "dependencies": {
23
- "axios": "^1.6.2",
24
- "cli-progress": "^3.12.0"
25
- }
26
- }
1
+ {
2
+ "name": "@officebeats/matrix-iptv-cli",
3
+ "version": "3.0.4",
4
+ "description": "The premium Terminal IPTV Decoder",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "matrix-iptv": "bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "postinstall": "node scripts/install-binary.js"
11
+ },
12
+ "keywords": [
13
+ "iptv",
14
+ "cli",
15
+ "tui",
16
+ "matrix",
17
+ "sports",
18
+ "xtream"
19
+ ],
20
+ "author": "Beats",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "axios": "^1.6.2",
24
+ "cli-progress": "^3.12.0"
25
+ }
26
+ }
@@ -1,83 +1,96 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const https = require("https");
4
- const os = require("os");
5
-
6
- const binaryName =
7
- os.platform() === "win32" ? "matrix-iptv.exe" : "matrix-iptv";
8
- const binDir = path.join(__dirname, "..", "bin");
9
- const binaryPath = path.join(binDir, binaryName);
10
-
11
- const platformMap = {
12
- win32: "windows.exe",
13
- linux: "linux",
14
- darwin: "macos",
15
- };
16
-
17
- const archMap = {
18
- x64: "x64",
19
- arm64: "arm64",
20
- };
21
-
22
- const platform = platformMap[os.platform()];
23
- if (!platform) {
24
- console.error(`Unsupported platform: ${os.platform()}`);
25
- process.exit(1);
26
- }
27
-
28
- // Note: Re-using the naming convention from install.ps1
29
- // https://github.com/officebeats/matrix-iptv/releases/latest/download/matrix-iptv-windows.exe
30
- const releaseUrl = `https://github.com/officebeats/matrix-iptv/releases/latest/download/matrix-iptv-${platform}`;
31
-
32
- console.log(`[*] Matrix IPTV CLI // One-Click Install`);
33
- console.log(`[*] Platform: ${os.platform()} (${os.arch()})`);
34
- console.log(`[*] Downloading: ${releaseUrl}`);
35
-
36
- if (!fs.existsSync(binDir)) {
37
- fs.mkdirSync(binDir, { recursive: true });
38
- }
39
-
40
- function download(url, dest) {
41
- return new Promise((resolve, reject) => {
42
- const file = fs.createWriteStream(dest);
43
- https
44
- .get(url, (response) => {
45
- if (response.statusCode === 302 || response.statusCode === 301) {
46
- // Handle Redirect
47
- download(response.headers.location, dest).then(resolve).catch(reject);
48
- return;
49
- }
50
- if (response.statusCode !== 200) {
51
- reject(new Error(`Failed to download: ${response.statusCode}`));
52
- return;
53
- }
54
- response.pipe(file);
55
- file.on("finish", () => {
56
- file.close();
57
- resolve();
58
- });
59
- })
60
- .on("error", (err) => {
61
- fs.unlink(dest, () => {});
62
- reject(err);
63
- });
64
- });
65
- }
66
-
67
- download(releaseUrl, binaryPath)
68
- .then(() => {
69
- console.log(`[+] Download complete.`);
70
- if (os.platform() !== "win32") {
71
- fs.chmodSync(binaryPath, "755");
72
- console.log(`[+] Executable permissions set.`);
73
- }
74
- console.log(`\n✅ Matrix IPTV CLI is ready.`);
75
- console.log(`Type 'matrix-iptv' to start.`);
76
- })
77
- .catch((err) => {
78
- console.error(`\n❌ Installation failed: ${err.message}`);
79
- console.log(
80
- `Please ensure the GitHub repository is public and has a 'latest' release.`
81
- );
82
- process.exit(1);
83
- });
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const https = require("https");
4
+ const os = require("os");
5
+
6
+ const binaryName =
7
+ os.platform() === "win32" ? "matrix-iptv.exe" : "matrix-iptv";
8
+ const binDir = path.join(__dirname, "..", "bin");
9
+ const binaryPath = path.join(binDir, binaryName);
10
+
11
+ const platformMap = {
12
+ win32: "windows.exe",
13
+ linux: "linux",
14
+ darwin: "macos",
15
+ };
16
+
17
+ const archMap = {
18
+ x64: "x64",
19
+ arm64: "arm64",
20
+ };
21
+
22
+ const platform = platformMap[os.platform()];
23
+ if (!platform) {
24
+ console.error(`Unsupported platform: ${os.platform()}`);
25
+ process.exit(1);
26
+ }
27
+
28
+ // Note: Re-using the naming convention from install.ps1
29
+ // https://github.com/officebeats/matrix-iptv/releases/latest/download/matrix-iptv-windows.exe
30
+ const releaseUrl = `https://github.com/officebeats/matrix-iptv/releases/latest/download/matrix-iptv-${platform}`;
31
+
32
+ console.log(`[*] Matrix IPTV CLI // One-Click Install`);
33
+ console.log(`[*] Platform: ${os.platform()} (${os.arch()})`);
34
+ console.log(`[*] Downloading: ${releaseUrl}`);
35
+
36
+ if (!fs.existsSync(binDir)) {
37
+ fs.mkdirSync(binDir, { recursive: true });
38
+ }
39
+
40
+ function download(url, dest) {
41
+ return new Promise((resolve, reject) => {
42
+ const file = fs.createWriteStream(dest);
43
+ https
44
+ .get(url, (response) => {
45
+ if (response.statusCode === 302 || response.statusCode === 301) {
46
+ // Handle Redirect
47
+ download(response.headers.location, dest).then(resolve).catch(reject);
48
+ return;
49
+ }
50
+ if (response.statusCode !== 200) {
51
+ reject(new Error(`Failed to download: ${response.statusCode}`));
52
+ return;
53
+ }
54
+ response.pipe(file);
55
+ file.on("finish", () => {
56
+ file.close();
57
+ resolve();
58
+ });
59
+ })
60
+ .on("error", (err) => {
61
+ fs.unlink(dest, () => {});
62
+ reject(err);
63
+ });
64
+ });
65
+ }
66
+
67
+ download(releaseUrl, binaryPath)
68
+ .then(() => {
69
+ console.log(`[+] Download complete.`);
70
+ if (os.platform() !== "win32") {
71
+ fs.chmodSync(binaryPath, "755");
72
+ console.log(`[+] Executable permissions set.`);
73
+ }
74
+
75
+ console.log(`\n✅ Matrix IPTV CLI installed successfully.`);
76
+
77
+ // Auto-launch if running in an interactive terminal
78
+ if (process.stdout.isTTY) {
79
+ console.log(`🚀 Launching Matrix IPTV...`);
80
+ const { spawn } = require("child_process");
81
+ const child = spawn(binaryPath, [], { stdio: "inherit" });
82
+
83
+ child.on("close", (code) => {
84
+ process.exit(code);
85
+ });
86
+ } else {
87
+ console.log(`Type 'matrix-iptv' to start.`);
88
+ }
89
+ })
90
+ .catch((err) => {
91
+ console.error(`\n❌ Installation failed: ${err.message}`);
92
+ console.log(
93
+ `Please ensure the GitHub repository is public and has a 'latest' release.`
94
+ );
95
+ process.exit(1);
96
+ });
@@ -0,0 +1,68 @@
1
+ const http = require("http");
2
+ const https = require("https");
3
+ const url = require("url");
4
+
5
+ const PORT = 8081;
6
+
7
+ const server = http.createServer((req, res) => {
8
+ // Enable CORS for all requests
9
+ res.setHeader("Access-Control-Allow-Origin", "*");
10
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
11
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
12
+
13
+ if (req.method === "OPTIONS") {
14
+ res.writeHead(200);
15
+ res.end();
16
+ return;
17
+ }
18
+
19
+ // Extract the actual target URL from the request URL path
20
+ // Example: http://localhost:8080/http://provider.com/get...
21
+ const requestUrl = req.url.slice(1); // Remove leading slash
22
+
23
+ if (!requestUrl.startsWith("http")) {
24
+ res.writeHead(400, { "Content-Type": "text/plain" });
25
+ res.end("Usage: http://localhost:8080/<TARGET_URL>");
26
+ return;
27
+ }
28
+
29
+ console.log(`[Proxy] Forwarding to: ${requestUrl}`);
30
+ const parsedUrl = url.parse(requestUrl);
31
+ console.log(`[Proxy] Target Host: ${parsedUrl.host}`);
32
+
33
+ const protocol = parsedUrl.protocol === "https:" ? https : http;
34
+
35
+ const headers = { ...req.headers };
36
+ headers.host = parsedUrl.host;
37
+ delete headers.origin;
38
+ delete headers.referer;
39
+
40
+ const options = {
41
+ method: req.method,
42
+ headers: headers,
43
+ };
44
+
45
+ const proxyReq = protocol.request(requestUrl, options, (proxyRes) => {
46
+ console.log(`[Proxy] Target Status: ${proxyRes.statusCode}`);
47
+ console.log(`[Proxy] Target Headers:`, proxyRes.headers);
48
+
49
+ res.writeHead(proxyRes.statusCode, {
50
+ ...proxyRes.headers,
51
+ "Access-Control-Allow-Origin": "*",
52
+ });
53
+ proxyRes.pipe(res);
54
+ });
55
+
56
+ proxyReq.on("error", (err) => {
57
+ console.error(`[Proxy Error] ${err.message}`);
58
+ res.writeHead(500, { "Content-Type": "text/plain" });
59
+ res.end(`Proxy Error: ${err.message}`);
60
+ });
61
+
62
+ req.pipe(proxyReq);
63
+ });
64
+
65
+ server.listen(PORT, () => {
66
+ console.log(`\n🚀 CORS Proxy running at http://localhost:${PORT}`);
67
+ console.log(`usage: http://localhost:${PORT}/<Target_URL>`);
68
+ });