@iptv/xtream-api
Version:
Standardized access to Xtream compatible player API
175 lines (174 loc) • 5.41 kB
JavaScript
class h {
baseUrl;
#o;
#s;
#i;
#r = "ts";
#e = {
profile: (e) => e,
serverInfo: (e) => e,
channelCategories: (e) => e,
movieCategories: (e) => e,
showCategories: (e) => e,
channels: (e) => e,
movies: (e) => e,
movie: (e) => e,
shows: (e) => e,
show: (e) => e,
shortEPG: (e) => e,
fullEPG: (e) => e
};
serializerType = "none";
userProfile;
constructor({
url: e,
username: t,
password: s,
preferredFormat: r,
serializer: i
}) {
if (!e)
throw new Error("The Xtream URL is required");
if (!t || !s)
throw new Error("The authentication credentials are required");
this.#s = t.trim(), this.#i = s.trim(), this.baseUrl = e.replace(/\/$/, ""), this.#o = this.baseUrl + `/player_api.php?username=${this.#s}&password=${this.#i}&action=`, r && (this.#r = r), i && (this.serializerType = i.type, this.#e = {
...this.#e,
...i.serializers
});
}
async #t(e) {
["get_live_streams", "get_vod_streams", "get_vod_info", "get_series_info"].includes(e.split("&")[0]) && this.userProfile === void 0 && (this.userProfile = (await this.#t("get_profile")).user_info);
const t = await fetch(`${this.#o}${e}`, {
headers: {
"Content-Type": "application/json"
}
});
if (!t.ok)
throw new Error(t.statusText);
return await t.json();
}
generateStreamUrl(e) {
if (e.type === "channel") {
let t = this.#r;
if (t === "rtmp")
return `${this.baseUrl}/live/${this.#s}/${this.#i}/${e.streamId}.ts`;
if (e.timeshift) {
const { start: s, duration: r } = e.timeshift, i = s.toISOString().replace(/:/g, "-").replace("T", ":").slice(0, -8);
return `${this.baseUrl}/timeshift/${this.#s}/${this.#i}/${r}/${i}/${e.streamId}.ts`;
}
return this.userProfile.allowed_output_formats.includes(e.extension) || (t = this.userProfile.allowed_output_formats[0]), `${this.baseUrl}/live/${this.#s}/${this.#i}/${e.streamId}.${t}`;
}
if (e.type === "episode")
return `${this.baseUrl}/series/${this.#s}/${this.#i}/${e.streamId}.${e.extension}`;
if (e.type === "movie")
return `${this.baseUrl}/movie/${this.#s}/${this.#i}/${e.streamId}.${e.extension}`;
}
async getProfile() {
const e = await this.#t("get_profile");
return this.#e.profile(e.user_info);
}
async getServerInfo() {
const e = await this.#t("get_server_info");
return this.#e.serverInfo(e.server_info);
}
async getChannelCategories() {
const e = await this.#t("get_live_categories");
return this.#e.channelCategories(e);
}
async getMovieCategories() {
const e = await this.#t("get_vod_categories");
return this.#e.movieCategories(e);
}
async getShowCategories() {
const e = await this.#t("get_series_categories");
return this.#e.showCategories(e);
}
async getChannels({ categoryId: e, page: t, limit: s } = {}) {
const r = "get_live_streams" + (e ? `&category_id=${e}` : "");
let i = await this.#t(r);
if (t) {
s || (s = 10);
const o = (t - 1) * s, n = o + s;
i = i.slice(o, n);
}
return i.forEach((o) => {
o.url = this.generateStreamUrl({
type: "channel",
streamId: o.stream_id,
extension: this.#r
});
}), this.#e.channels(i);
}
async getMovies({ categoryId: e, page: t, limit: s } = {}) {
const r = "get_vod_streams" + (e ? `&category_id=${e}` : "");
let i = await this.#t(r);
if (t) {
s || (s = 10);
const o = (t - 1) * s, n = o + s;
i = i.slice(o, n);
}
return i.forEach((o) => {
o.url = this.generateStreamUrl({
type: "movie",
streamId: o.stream_id,
extension: o.container_extension
});
}), this.#e.movies(i);
}
async getMovie({
movieId: e
}) {
const t = await this.#t("get_vod_info&vod_id=" + e);
if (Array.isArray(t.info) && t.info.length === 0)
throw new Error("Movie Not Found");
return t.url = this.generateStreamUrl({
type: "movie",
streamId: t.movie_data.stream_id,
extension: t.movie_data.container_extension
}), this.#e.movie(t);
}
async getShows({ categoryId: e, page: t, limit: s } = {}) {
const r = "get_series" + (e ? `&category_id=${e}` : "");
let i = await this.#t(r);
if (t) {
s || (s = 10);
const o = (t - 1) * s, n = o + s;
i = i.slice(o, n);
}
return this.#e.shows(i);
}
async getShow({ showId: e }) {
const t = await this.#t("get_series_info&series_id=" + e);
if (t.info.name === null)
throw new Error("Show Not Found");
return t.info.series_id = Number(e), Object.keys(t.episodes).forEach((s) => {
t.episodes[s].forEach((r) => {
r.url = this.generateStreamUrl({
type: "episode",
streamId: r.id,
extension: r.container_extension
});
});
}), this.#e.show(t);
}
async getShortEPG({
channelId: e,
limit: t
}) {
const s = `get_short_epg&stream_id=${e}` + (t ? `&limit=${t}` : ""), r = await this.#t(s);
return this.#e.shortEPG(r);
}
async getFullEPG({
channelId: e
}) {
const t = `get_simple_data_table&stream_id=${e}`, s = await this.#t(t);
return this.#e.fullEPG(s);
}
}
function c(a, e) {
return { type: a, serializers: e };
}
export {
h as Xtream,
c as defineSerializers
};