Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@hyrious/blivec

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hyrious/blivec - npm Package Compare versions

Comparing version 0.3.3 to 0.3.4

dist/index.d.ts

28

./dist/index.js

@@ -55,2 +55,17 @@ "use strict";

timer_heartbeat = /* @__PURE__ */ setTimeout(noop);
_temp = null;
pause() {
this._temp || (this._temp = []);
(this.events.pause || noop)();
}
resume() {
(this.events.resume || noop)();
const temp = this._temp;
if (temp) {
this._temp = null;
for (const data of temp) {
(this.events.message || noop)(data);
}
}
}
_closed = false;

@@ -70,3 +85,7 @@ _connect_index = 0;

this.buffer = EMPTY_BUFFER;
const socket = await this.connect();
const socket = await this.connect().catch(() => null);
if (socket === null) {
this._on_close();
return;
}
this.socket = socket;

@@ -105,2 +124,3 @@ this.timer_reconnect = setTimeout(this.reconnect.bind(this), 45e3);

(this.events.error || noop)(err);
this.socket = null;
}

@@ -133,3 +153,7 @@ _on_data(buffer) {

} else if (type === "message") {
(this.events.message || noop)(data);
if (this._temp) {
this._temp.push(data);
} else {
(this.events.message || noop)(data);
}
}

@@ -136,0 +160,0 @@ }

250

dist/bin.js

@@ -5,2 +5,3 @@ #!/usr/bin/env node

import fs from "fs";
import tty from "tty";
import { join } from "path";

@@ -29,9 +30,27 @@ import rl from "readline";

`.trim();
const hasColors = tty.WriteStream.prototype.hasColors();
function help() {
console.log(help_text);
}
function format(beg, end) {
return hasColors ? (str) => "\x1B[" + beg + "m" + str + "\x1B[" + end + "m" : (str) => str;
}
const red = format(31, 39);
const cyan = format(36, 39);
const black = format(30, 39);
const bgRed = format(41, 49);
function print_error(msg) {
console.error(`${bgRed(black("\u2009ERROR\u2009"))} ${red(msg)}`);
}
function print_info(msg) {
console.error(`${cyan("\u2009INFO\u2009")} ${cyan(msg)}`);
}
function error_exit(error) {
print_error(error.message);
process.exit(1);
}
function listen(id, { json = false } = {}) {
let repl;
function setup_repl() {
if (process.stdout.isTTY) {
if (process.stdout.isTTY && !repl) {
console.log('[blivec] type "> message" to send danmaku');

@@ -49,3 +68,5 @@ repl = rl.createInterface({

line = line.slice(2);
send(id, line).catch(console.error);
send(id, line).catch((error) => {
print_error(error.message);
});
} else {

@@ -63,15 +84,21 @@ console.log(

}
let first = 0;
const events = json ? {
init: (data) => console.log(JSON.stringify({ cmd: "init", data })),
message: (data) => console.log(JSON.stringify(data)),
error: console.error
error: (err) => print_error(err.message)
} : {
init({ title, live_status, live_start_time }) {
if (live_status === 1) {
const time = new Date(live_start_time * 1e3).toLocaleString();
console.log(`[blivec] listening ${title} (start at ${time})`);
if (first === 0) {
if (live_status === 1) {
const time = new Date(live_start_time * 1e3).toLocaleString();
console.log(`[blivec] listening ${title} (start at ${time})`);
} else {
console.log(`[blivec] listening ${title} (offline)`);
}
setup_repl();
} else {
console.log(`[blivec] listening ${title} (offline)`);
print_info(`reconnected (x${first})`);
}
setup_repl();
first++;
},

@@ -85,4 +112,6 @@ message(a) {

},
error: console.error,
quit: () => repl && repl.close()
error: (err) => print_error(err.message),
quit: () => repl && repl.close(),
pause: () => repl && repl.pause(),
resume: () => repl && repl.resume()
};

@@ -93,7 +122,7 @@ return new Connection(id, events);

function example() {
console.log("Example content:");
console.log("");
console.log("SESSDATA=...");
console.log("bili_jct=...");
console.log();
console.error("Example content:");
console.error("");
console.error("SESSDATA=...");
console.error("bili_jct=...");
console.error();
}

@@ -115,3 +144,3 @@ function cookiePath(path2) {

if (!path) {
console.log('Please create a file "cookie.txt" in current directory.');
console.error('Please create a file "cookie.txt" in current directory.');
example();

@@ -131,5 +160,7 @@ process.exit(1);

if (env.SESSDATA && env.bili_jct) {
await sendDanmaku(id, message, env).catch(console.error);
await sendDanmaku(id, message, env).catch((err) => {
print_error(err.message);
});
} else {
console.log("Invalid cookie.txt");
print_error("Invalid cookie.txt");
example();

@@ -158,7 +189,12 @@ process.exit(1);

} catch (err) {
console.error("Error:", err.message);
process.exit(1);
error_exit(err);
}
}
async function D(id, { interval = 1, mpv = false } = {}) {
console.log(
`[blivec] DD ${id}`,
interval > 0 ? `every ${interval} minutes` : "once"
);
let con;
let child;
const headers = [

@@ -168,79 +204,109 @@ "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.1) Gecko/20100101 Firefox/60.1",

];
let info = null;
console.log(
`[blivec] DD ${id}`,
interval > 0 ? `every ${interval} minutes` : "once"
);
while (info === null) {
info = await getRoomPlayInfo(id).catch(() => null);
if (info && !await testUrl(fst(info.streams).url, headers))
info = null;
if (info || interval === 0)
break;
await setTimeout(interval * 60 * 1e3);
async function poll() {
let info = null;
while (info === null) {
info = await getRoomPlayInfo(id).catch(() => null);
if (info && !await testUrl(fst(info.streams).url, headers))
info = null;
if (info || interval === 0)
break;
await setTimeout(interval * 60 * 1e3);
}
function fst(obj) {
for (const key in obj)
return obj[key];
return {};
}
return info;
}
function fst(obj) {
for (const key in obj)
return obj[key];
return {};
}
if (info === null) {
return;
}
const { title, streams } = info;
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Title:", title);
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Available streams:");
const names = Object.keys(streams);
names.forEach((name, index) => {
console.log(` ${index + 1}: ${name}`);
});
const input = rl.createInterface({
input: process.stdin,
output: process.stdout
});
const choices = Array.from({ length: names.length }, (_, i2) => i2 + 1);
const hint = [...choices, "Y=1", "max", "n"].join("/");
const choice = await new Promise((resolve) => {
input.question(`[blivec] Choose a stream, or give up: (${hint}) `, (a) => {
input.close();
resolve(a || "Y");
async function ask(info) {
const { title, streams } = info;
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Title:", title);
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Available streams:");
const names = Object.keys(streams);
const width = names.length > 9 ? 2 : 1;
names.forEach((name, index) => {
console.log(` ${String(index + 1).padStart(width)}: ${name}`);
});
});
const i = Number.parseInt(choice);
let selected = names[0];
if (Number.isSafeInteger(i) && 1 <= i && i <= names.length) {
selected = names[i - 1];
} else {
const a = choice[0].toLowerCase();
if (a === "n") {
return;
} else if (a === "m") {
selected = names.reduce(
(a2, b) => streams[a2].qn > streams[b].qn ? a2 : b
const input = rl.createInterface({
input: process.stdin,
output: process.stdout
});
const choices = Array.from({ length: names.length }, (_, i2) => i2 + 1);
const hint = [...choices, "Y=1", "max", "n"].join("/");
const choice = await new Promise((resolve) => {
input.question(
`[blivec] Choose a stream, or give up: (${hint}) `,
(a) => {
input.close();
resolve(a || "Y");
}
);
});
const i = Number.parseInt(choice);
let selected2 = names[0];
if (Number.isSafeInteger(i) && 1 <= i && i <= names.length) {
selected2 = names[i - 1];
} else {
const a = choice[0].toLowerCase();
if (a === "n") {
return;
} else if (a === "m") {
selected2 = names.reduce(
(a2, b) => streams[a2].qn > streams[b].qn ? a2 : b
);
}
}
return selected2;
}
console.log("[blivec] Now playing:", `[${selected}] ${title}`);
const url = streams[selected].url;
let child;
if (mpv) {
const args = ["--quiet"];
args.push("--http-header-fields=" + headers.join(","));
args.push("--title=" + title);
args.push("--geometry=50%");
args.push(url);
child = cp.spawn("mpv", args, { stdio: "inherit", detached: true });
child.unref();
} else {
const args = ["-hide_banner", "-loglevel", "error"];
args.push("-headers", headers.map((e) => e + "\r\n").join(""));
args.push("-window_title", title);
args.push("-x", "1280", "-y", "720");
args.push(url);
child = cp.spawn("ffplay", args, { stdio: "inherit" });
function play(url, title) {
let child2;
if (mpv) {
const args = ["--quiet"];
args.push("--http-header-fields=" + headers.join(","));
args.push("--title=" + title);
args.push("--geometry=50%");
args.push(url);
child2 = cp.spawn("mpv", args, { stdio: "inherit", detached: true });
child2.unref();
} else {
const args = ["-hide_banner", "-loglevel", "error"];
args.push("-headers", headers.map((e) => e + "\r\n").join(""));
args.push("-window_title", title);
args.push("-x", "1280", "-y", "720");
args.push(url);
child2 = cp.spawn("ffplay", args, { stdio: "inherit" });
}
return child2;
}
const con = listen(id);
child.once("exit", () => con.close());
let selected;
async function replay() {
const info = await poll();
if (!info)
return;
const { title } = info;
selected ||= await ask(info);
if (!selected)
return;
console.log("[blivec] Now playing:", `[${selected}] ${title}`);
child = play(info.streams[selected].url, title);
con ||= listen(id);
con.resume();
child.on("exit", () => {
con.pause();
setTimeout(100).then(replay);
});
}
await replay();
const quit = con.events.quit;
con.events.quit = () => {
quit && quit();
if (process.platform === "win32") {
cp.execSync("taskkill /pid " + child.pid + " /T /F");
} else {
process.kill(-child.pid, "SIGTERM");
}
};
return con;

@@ -256,3 +322,3 @@ }

else
console.log("\n[blivec] closing...");
console.log("[blivec] closing...");
con.close();

@@ -259,0 +325,0 @@ });

@@ -55,2 +55,17 @@ "use strict";

timer_heartbeat = /* @__PURE__ */ setTimeout(noop);
_temp = null;
pause() {
this._temp || (this._temp = []);
(this.events.pause || noop)();
}
resume() {
(this.events.resume || noop)();
const temp = this._temp;
if (temp) {
this._temp = null;
for (const data of temp) {
(this.events.message || noop)(data);
}
}
}
_closed = false;

@@ -70,3 +85,7 @@ _connect_index = 0;

this.buffer = EMPTY_BUFFER;
const socket = await this.connect();
const socket = await this.connect().catch(() => null);
if (socket === null) {
this._on_close();
return;
}
this.socket = socket;

@@ -105,2 +124,3 @@ this.timer_reconnect = setTimeout(this.reconnect.bind(this), 45e3);

(this.events.error || noop)(err);
this.socket = null;
}

@@ -133,3 +153,7 @@ _on_data(buffer) {

} else if (type === "message") {
(this.events.message || noop)(data);
if (this._temp) {
this._temp.push(data);
} else {
(this.events.message || noop)(data);
}
}

@@ -136,0 +160,0 @@ }

{
"name": "@hyrious/blivec",
"version": "0.3.3",
"version": "0.3.4",
"description": "bilibili live cli",

@@ -5,0 +5,0 @@ "type": "module",

#!/usr/bin/env node
import os from "os";
import fs from "fs";
import tty from "tty";
import { join } from "path";

@@ -30,2 +31,4 @@ import rl from "readline";

const hasColors = tty.WriteStream.prototype.hasColors();
function help() {

@@ -35,2 +38,25 @@ console.log(help_text);

function format(beg: number, end: number) {
return hasColors
? (str: any) => "\x1B[" + beg + "m" + str + "\x1B[" + end + "m"
: (str: any) => str;
}
const red = format(31, 39);
const cyan = format(36, 39);
const black = format(30, 39);
const bgRed = format(41, 49);
function print_error(msg: string) {
console.error(`${bgRed(black("\u2009ERROR\u2009"))} ${red(msg)}`);
}
function print_info(msg: string) {
console.error(`${cyan("\u2009INFO\u2009")} ${cyan(msg)}`);
}
function error_exit(error: Error): never {
print_error(error.message);
process.exit(1);
}
function listen(id: number, { json = false } = {}) {

@@ -40,3 +66,3 @@ let repl: rl.Interface | undefined;

function setup_repl() {
if (process.stdout.isTTY) {
if (process.stdout.isTTY && !repl) {
console.log('[blivec] type "> message" to send danmaku');

@@ -54,3 +80,5 @@ repl = rl.createInterface({

line = line.slice(2);
send(id, line).catch(console.error);
send(id, line).catch((error: Error) => {
print_error(error.message);
});
} else {

@@ -69,2 +97,3 @@ console.log(

let first = 0;
const events: Events = json

@@ -74,13 +103,18 @@ ? {

message: (data) => console.log(JSON.stringify(data)),
error: console.error,
error: (err) => print_error(err.message),
}
: {
init({ title, live_status, live_start_time }) {
if (live_status === 1) {
const time = new Date(live_start_time * 1000).toLocaleString();
console.log(`[blivec] listening ${title} (start at ${time})`);
if (first === 0) {
if (live_status === 1) {
const time = new Date(live_start_time * 1000).toLocaleString();
console.log(`[blivec] listening ${title} (start at ${time})`);
} else {
console.log(`[blivec] listening ${title} (offline)`);
}
setup_repl();
} else {
console.log(`[blivec] listening ${title} (offline)`);
print_info(`reconnected (x${first})`);
}
setup_repl();
first++;
},

@@ -94,4 +128,6 @@ message(a) {

},
error: console.error,
error: (err) => print_error(err.message),
quit: () => repl && repl.close(),
pause: () => repl && repl.pause(),
resume: () => repl && repl.resume(),
};

@@ -104,7 +140,7 @@

function example() {
console.log("Example content:");
console.log("");
console.log("SESSDATA=...");
console.log("bili_jct=...");
console.log();
console.error("Example content:");
console.error("");
console.error("SESSDATA=...");
console.error("bili_jct=...");
console.error();
}

@@ -124,3 +160,3 @@

if (!path) {
console.log('Please create a file "cookie.txt" in current directory.');
console.error('Please create a file "cookie.txt" in current directory.');
example();

@@ -142,5 +178,7 @@ process.exit(1);

if (env.SESSDATA && env.bili_jct) {
await sendDanmaku(id, message, env).catch(console.error);
await sendDanmaku(id, message, env).catch((err) => {
print_error(err.message);
});
} else {
console.log("Invalid cookie.txt");
print_error("Invalid cookie.txt");
example();

@@ -170,4 +208,3 @@ process.exit(1);

} catch (err: any) {
console.error("Error:", err.message);
process.exit(1);
error_exit(err);
}

@@ -177,2 +214,10 @@ }

async function D(id: number, { interval = 1, mpv = false } = {}) {
console.log(
`[blivec] DD ${id}`,
interval > 0 ? `every ${interval} minutes` : "once"
);
let con!: Connection;
let child!: cp.ChildProcess;
const headers = [

@@ -184,82 +229,113 @@ "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.1) Gecko/20100101 Firefox/60.1",

type RoomPlayInfo = Awaited<ReturnType<typeof getRoomPlayInfo>>;
let info: RoomPlayInfo | null = null;
console.log(
`[blivec] DD ${id}`,
interval > 0 ? `every ${interval} minutes` : "once"
);
while (info === null) {
info = await getRoomPlayInfo(id).catch(() => null);
if (info && !(await testUrl(fst(info.streams).url, headers))) info = null;
if (info || interval === 0) break;
await setTimeout(interval * 60 * 1000);
async function poll() {
let info: RoomPlayInfo | null = null;
while (info === null) {
info = await getRoomPlayInfo(id).catch(() => null);
if (info && !(await testUrl(fst(info.streams).url, headers))) info = null;
if (info || interval === 0) break;
await setTimeout(interval * 60 * 1000);
}
function fst<T extends {}>(obj: T): T[keyof T] {
for (const key in obj) return obj[key];
return {} as any;
}
return info;
}
function fst<T extends {}>(obj: T): T[keyof T] {
for (const key in obj) return obj[key];
return {} as any;
}
if (info === null) {
return;
}
async function ask(info: RoomPlayInfo) {
const { title, streams } = info;
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Title:", title);
console.log("[blivec] " + "=====".repeat(10));
const { title, streams } = info;
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Title:", title);
console.log("[blivec] " + "=====".repeat(10));
console.log("[blivec] Available streams:");
const names = Object.keys(streams);
names.forEach((name, index) => {
console.log(` ${index + 1}: ${name}`);
});
const input = rl.createInterface({
input: process.stdin,
output: process.stdout,
});
const choices = Array.from({ length: names.length }, (_, i) => i + 1);
const hint = [...choices, "Y=1", "max", "n"].join("/");
const choice = await new Promise<string>((resolve) => {
input.question(`[blivec] Choose a stream, or give up: (${hint}) `, (a) => {
input.close();
resolve(a || "Y");
console.log("[blivec] Available streams:");
const names = Object.keys(streams);
const width = names.length > 9 ? 2 : 1;
names.forEach((name, index) => {
console.log(` ${String(index + 1).padStart(width)}: ${name}`);
});
});
const i = Number.parseInt(choice);
let selected = names[0];
if (Number.isSafeInteger(i) && 1 <= i && i <= names.length) {
selected = names[i - 1];
} else {
const a = choice[0].toLowerCase();
if (a === "n") {
return;
} else if (a === "m") {
selected = names.reduce((a, b) =>
streams[a].qn > streams[b].qn ? a : b
const input = rl.createInterface({
input: process.stdin,
output: process.stdout,
});
const choices = Array.from({ length: names.length }, (_, i) => i + 1);
const hint = [...choices, "Y=1", "max", "n"].join("/");
const choice = await new Promise<string>((resolve) => {
input.question(
`[blivec] Choose a stream, or give up: (${hint}) `,
(a) => {
input.close();
resolve(a || "Y");
}
);
});
const i = Number.parseInt(choice);
let selected = names[0];
if (Number.isSafeInteger(i) && 1 <= i && i <= names.length) {
selected = names[i - 1];
} else {
const a = choice[0].toLowerCase();
if (a === "n") {
return;
} else if (a === "m") {
selected = names.reduce((a, b) =>
streams[a].qn > streams[b].qn ? a : b
);
}
}
return selected;
}
console.log("[blivec] Now playing:", `[${selected}] ${title}`);
const url = streams[selected].url;
function play(url: string, title: string) {
let child: ChildProcess;
if (mpv) {
const args = ["--quiet"];
args.push("--http-header-fields=" + headers.join(","));
args.push("--title=" + title);
args.push("--geometry=50%");
args.push(url);
child = cp.spawn("mpv", args, { stdio: "inherit", detached: true });
child.unref();
} else {
const args = ["-hide_banner", "-loglevel", "error"];
args.push("-headers", headers.map((e) => e + "\r\n").join(""));
args.push("-window_title", title);
args.push("-x", "1280", "-y", "720");
args.push(url);
child = cp.spawn("ffplay", args, { stdio: "inherit" });
}
return child;
}
let child: ChildProcess;
if (mpv) {
const args = ["--quiet"];
args.push("--http-header-fields=" + headers.join(","));
args.push("--title=" + title);
args.push("--geometry=50%");
args.push(url);
child = cp.spawn("mpv", args, { stdio: "inherit", detached: true });
child.unref();
} else {
const args = ["-hide_banner", "-loglevel", "error"];
args.push("-headers", headers.map((e) => e + "\r\n").join(""));
args.push("-window_title", title);
args.push("-x", "1280", "-y", "720");
args.push(url);
child = cp.spawn("ffplay", args, { stdio: "inherit" });
let selected: string | undefined;
async function replay() {
const info = await poll();
if (!info) return;
const { title } = info;
selected ||= await ask(info);
if (!selected) return;
console.log("[blivec] Now playing:", `[${selected}] ${title}`);
child = play(info.streams[selected].url, title);
con ||= listen(id);
con.resume();
child.on("exit", () => {
con.pause();
setTimeout(100).then(replay);
});
}
const con = listen(id);
child.once("exit", () => con.close());
await replay();
const quit = con.events.quit;
con.events.quit = () => {
quit && quit();
if (process.platform === "win32") {
cp.execSync("taskkill /pid " + child.pid + " /T /F");
} else {
process.kill(-child.pid!, "SIGTERM");
}
};
return con;

@@ -275,3 +351,3 @@ }

if (json) console.log(JSON.stringify({ cmd: "exit" }));
else console.log("\n[blivec] closing...");
else console.log("[blivec] closing...");
con.close();

@@ -278,0 +354,0 @@ });

@@ -72,4 +72,6 @@ import https from "https";

message?: (data: any) => void;
error?: (err: any) => void;
error?: (err: Error) => void;
quit?: () => void;
pause?: () => void;
resume?: () => void;
}

@@ -89,2 +91,18 @@

_temp: any[] | null = null;
pause() {
this._temp || (this._temp = []);
(this.events.pause || noop)();
}
resume() {
(this.events.resume || noop)();
const temp = this._temp;
if (temp) {
this._temp = null;
for (const data of temp) {
(this.events.message || noop)(data);
}
}
}
_closed = false;

@@ -108,3 +126,7 @@ _connect_index = 0;

const socket = await this.connect();
const socket = await this.connect().catch(() => null);
if (socket === null) {
this._on_close();
return;
}
this.socket = socket;

@@ -146,4 +168,5 @@ this.timer_reconnect = setTimeout(this.reconnect.bind(this), 45e3);

_on_error(err: any) {
_on_error(err: Error) {
(this.events.error || noop)(err);
this.socket = null;
}

@@ -180,3 +203,7 @@

} else if (type === "message") {
(this.events.message || noop)(data);
if (this._temp) {
this._temp.push(data);
} else {
(this.events.message || noop)(data);
}
}

@@ -183,0 +210,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc