JavaScript SDK
SDK versátil para integração com API Xtream UI em Node.js e Browser
Instalação
Para Node.js, instale usando npm ou yarn:
NPM
npm install axios
package.json
{
"name": "xtream-api-client",
"version": "1.0.0",
"dependencies": {
"axios": "^1.4.0"
},
"type": "module"
}
Para uso no browser, inclua via CDN:
CDN
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
Configuração
Crie a classe principal do SDK:
xtream-api.js
class XtreamAPI {
constructor(baseUrl, username = null, password = null) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.username = username;
this.password = password;
// Configurar axios
this.client = axios.create({
baseURL: this.baseUrl,
timeout: 30000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
// Interceptor para logs (opcional)
this.client.interceptors.request.use(
config => {
console.log(`[API] ${config.method.toUpperCase()} ${config.url}`);
return config;
},
error => Promise.reject(error)
);
this.client.interceptors.response.use(
response => response,
error => {
console.error(`[API Error] ${error.message}`);
return Promise.reject(error);
}
);
}
async _makeRequest(endpoint, params = {}) {
try {
const response = await this.client.get(endpoint, { params });
return response.data;
} catch (error) {
throw new Error(`Request failed: ${error.message}`);
}
}
async _makePostRequest(endpoint, data = {}) {
try {
const response = await this.client.post(endpoint, data);
return response.data;
} catch (error) {
throw new Error(`Request failed: ${error.message}`);
}
}
}
Autenticação
Métodos para autenticação e verificação de credenciais:
Métodos de Autenticação
async authenticate(username, password) {
const params = {
username: username,
password: password
};
const response = await this._makeRequest('/player_api.php', params);
if (response.user_info) {
this.username = username;
this.password = password;
return response;
}
throw new Error('Invalid credentials');
}
async getUserInfo() {
if (!this.username || !this.password) {
throw new Error('User not authenticated');
}
const params = {
username: this.username,
password: this.password
};
return await this._makeRequest('/player_api.php', params);
}
async panelLogin(username, password) {
const data = new URLSearchParams({
username: username,
password: password
});
const response = await this._makePostRequest('/api.php?action=login', data);
if (response.status === 'success') {
return response.token;
}
throw new Error('Panel login failed');
}
Gerenciamento de Usuários
Métodos para criar, editar e gerenciar usuários:
Métodos de Usuários
async createUser(token, userData) {
const data = new URLSearchParams({
action: 'user',
sub: 'create',
token: token,
...userData
});
return await this._makePostRequest('/api.php', data);
}
async editUser(token, userId, userData) {
const data = new URLSearchParams({
action: 'user',
sub: 'edit',
user_id: userId,
token: token,
...userData
});
return await this._makePostRequest('/api.php', data);
}
async deleteUser(token, userId) {
const data = new URLSearchParams({
action: 'user',
sub: 'delete',
user_id: userId,
token: token
});
return await this._makePostRequest('/api.php', data);
}
async getUserDetails(token, userId) {
const params = {
action: 'user',
sub: 'info',
user_id: userId,
token: token
};
return await this._makeRequest('/api.php', params);
}
async getAllUsers(token) {
const params = {
action: 'user',
sub: 'list',
token: token
};
return await this._makeRequest('/api.php', params);
}
Canais e Conteúdo
Métodos para gerenciar canais, VOD e séries:
Métodos de Conteúdo
async getLiveStreams() {
const params = {
username: this.username,
password: this.password,
action: 'get_live_streams'
};
return await this._makeRequest('/player_api.php', params);
}
async getVodStreams() {
const params = {
username: this.username,
password: this.password,
action: 'get_vod_streams'
};
return await this._makeRequest('/player_api.php', params);
}
async getSeries() {
const params = {
username: this.username,
password: this.password,
action: 'get_series'
};
return await this._makeRequest('/player_api.php', params);
}
async getStreamInfo(streamId, type = 'live') {
const params = {
username: this.username,
password: this.password,
action: `get_${type}_info`,
stream_id: streamId
};
return await this._makeRequest('/player_api.php', params);
}
async getCategories(type = 'live') {
const actionMap = {
live: 'get_live_categories',
vod: 'get_vod_categories',
series: 'get_series_categories'
};
const params = {
username: this.username,
password: this.password,
action: actionMap[type] || 'get_live_categories'
};
return await this._makeRequest('/player_api.php', params);
}
async getAllContent() {
const [liveStreams, vodStreams, series] = await Promise.all([
this.getLiveStreams(),
this.getVodStreams(),
this.getSeries()
]);
return {
liveStreams,
vodStreams,
series
};
}
Relatórios
Métodos para gerar relatórios e estatísticas:
Métodos de Relatórios
async getServerStats(token) {
const params = {
action: 'server_stats',
token: token
};
return await this._makeRequest('/api.php', params);
}
async getUserConnections(token, userId = null) {
const params = {
action: 'user_activity',
token: token
};
if (userId) {
params.user_id = userId;
}
return await this._makeRequest('/api.php', params);
}
async getStreamStats(token, streamId, type = 'live') {
const params = {
action: 'stream_stats',
token: token,
stream_id: streamId,
type: type
};
return await this._makeRequest('/api.php', params);
}
Node.js
Exemplo de uso em Node.js com ES6 modules:
exemplo-nodejs.js
import axios from 'axios';
import fs from 'fs/promises';
import { XtreamAPI } from './xtream-api.js';
async function exemploCompleto() {
try {
// Inicializar SDK
const api = new XtreamAPI('http://dominio_da_instancia:8080');
// Autenticar usuário
const userAuth = await api.authenticate('usuario_teste', 'senha123');
console.log(`Usuário autenticado: ${userAuth.user_info.username}`);
// Login no painel
const token = await api.panelLogin('admin', 'admin_password');
console.log(`Token obtido: ${token.substring(0, 10)}...`);
// Criar novo usuário
const novoUsuario = {
username: `novo_usuario_${Date.now()}`,
password: 'senha_forte_123',
email: 'usuario@email.com',
exp_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
max_connections: 2,
is_trial: 0,
enabled: 1
};
const resultado = await api.createUser(token, novoUsuario);
if (resultado.status === 'success') {
console.log(`Usuário criado! ID: ${resultado.user_id}`);
// Obter todo o conteúdo de forma paralela
const content = await api.getAllContent();
console.log(`Live Streams: ${content.liveStreams.length}`);
console.log(`VOD Streams: ${content.vodStreams.length}`);
console.log(`Series: ${content.series.length}`);
// Salvar relatório em arquivo
const relatorio = {
data: new Date().toISOString(),
usuario_criado: resultado.user_id,
estatisticas: {
canais_live: content.liveStreams.length,
vod: content.vodStreams.length,
series: content.series.length
}
};
await fs.writeFile(
'./relatorio_xtream.json',
JSON.stringify(relatorio, null, 2)
);
console.log('Relatório salvo em relatorio_xtream.json');
} else {
console.error(`Erro ao criar usuário: ${resultado.message}`);
}
} catch (error) {
console.error(`Erro: ${error.message}`);
// Log de erro com timestamp
const errorLog = `${new Date().toISOString()} - ERRO: ${error.message}\n`;
await fs.appendFile('./xtream_errors.log', errorLog);
}
}
// Executar exemplo
exemploCompleto();
Browser
Exemplo de uso no browser com interface web:
exemplo-browser.html
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Xtream API - Demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1>Xtream API Demo</h1>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Autenticação</h5>
</div>
<div class="card-body">
<form id="authForm">
<div class="mb-3">
<label class="form-label">Servidor</label>
<input type="text" class="form-control" id="servidor"
value="http://dominio_da_instancia:8080">
</div>
<div class="mb-3">
<label class="form-label">Usuário</label>
<input type="text" class="form-control" id="usuario">
</div>
<div class="mb-3">
<label class="form-label">Senha</label>
<input type="password" class="form-control" id="senha">
</div>
<button type="submit" class="btn btn-primary">Conectar</button>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Resultado</h5>
</div>
<div class="card-body">
<pre id="resultado"></pre>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5>Canais Disponíveis</h5>
</div>
<div class="card-body">
<div id="canais"></div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
class XtreamAPI {
constructor(baseUrl) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.username = null;
this.password = null;
}
async authenticate(username, password) {
const params = new URLSearchParams({
username: username,
password: password
});
const response = await axios.get(`${this.baseUrl}/player_api.php?${params}`);
if (response.data.user_info) {
this.username = username;
this.password = password;
return response.data;
}
throw new Error('Credenciais inválidas');
}
async getLiveStreams() {
const params = new URLSearchParams({
username: this.username,
password: this.password,
action: 'get_live_streams'
});
const response = await axios.get(`${this.baseUrl}/player_api.php?${params}`);
return response.data;
}
}
let api = null;
document.getElementById('authForm').addEventListener('submit', async (e) => {
e.preventDefault();
const servidor = document.getElementById('servidor').value;
const usuario = document.getElementById('usuario').value;
const senha = document.getElementById('senha').value;
try {
api = new XtreamAPI(servidor);
const result = await api.authenticate(usuario, senha);
document.getElementById('resultado').textContent = JSON.stringify(result, null, 2);
// Carregar canais
const canais = await api.getLiveStreams();
mostrarCanais(canais.slice(0, 10)); // Primeiros 10 canais
} catch (error) {
document.getElementById('resultado').textContent = `Erro: ${error.message}`;
}
});
function mostrarCanais(canais) {
const container = document.getElementById('canais');
container.innerHTML = '';
canais.forEach(canal => {
const div = document.createElement('div');
div.className = 'alert alert-info';
div.innerHTML = `
<strong>${canal.name || 'Canal sem nome'}</strong><br>
ID: ${canal.stream_id}<br>
Categoria: ${canal.category_id}
`;
container.appendChild(div);
});
}
</script>
</body>
</html>
Tratamento de Erros
Implementação avançada de tratamento de erros e retry:
error-handling.js
class XtreamAPIAdvanced extends XtreamAPI {
constructor(baseUrl, options = {}) {
super(baseUrl);
this.options = {
maxRetries: options.maxRetries || 3,
retryDelay: options.retryDelay || 1000,
enableCache: options.enableCache || true,
cacheTimeout: options.cacheTimeout || 300000 // 5 minutos
};
this.cache = new Map();
this.requestQueue = new Map();
}
async _makeRequestWithRetry(endpoint, params = {}, retries = 0) {
try {
// Verificar cache se habilitado
if (this.options.enableCache) {
const cacheKey = this._getCacheKey(endpoint, params);
const cached = this.cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < this.options.cacheTimeout) {
console.log(`[Cache Hit] ${endpoint}`);
return cached.data;
}
}
// Evitar requisições duplicadas
const requestKey = this._getRequestKey(endpoint, params);
if (this.requestQueue.has(requestKey)) {
return await this.requestQueue.get(requestKey);
}
// Fazer requisição
const requestPromise = this._makeRequest(endpoint, params);
this.requestQueue.set(requestKey, requestPromise);
const result = await requestPromise;
// Salvar no cache
if (this.options.enableCache) {
const cacheKey = this._getCacheKey(endpoint, params);
this.cache.set(cacheKey, {
data: result,
timestamp: Date.now()
});
}
// Remover da fila
this.requestQueue.delete(requestKey);
return result;
} catch (error) {
this.requestQueue.delete(this._getRequestKey(endpoint, params));
if (retries < this.options.maxRetries) {
console.warn(`[Retry ${retries + 1}/${this.options.maxRetries}] ${endpoint}: ${error.message}`);
// Delay antes do retry
await new Promise(resolve =>
setTimeout(resolve, this.options.retryDelay * (retries + 1))
);
return this._makeRequestWithRetry(endpoint, params, retries + 1);
}
throw new Error(`Request failed after ${this.options.maxRetries} retries: ${error.message}`);
}
}
_getCacheKey(endpoint, params) {
return `${endpoint}:${JSON.stringify(params)}`;
}
_getRequestKey(endpoint, params) {
return `${endpoint}:${JSON.stringify(params)}`;
}
// Sobrescrever métodos para usar retry
async authenticate(username, password) {
const params = { username, password };
const response = await this._makeRequestWithRetry('/player_api.php', params);
if (response.user_info) {
this.username = username;
this.password = password;
return response;
}
throw new Error('Invalid credentials');
}
async getLiveStreams() {
const params = {
username: this.username,
password: this.password,
action: 'get_live_streams'
};
return await this._makeRequestWithRetry('/player_api.php', params);
}
// Método para limpar cache
clearCache() {
this.cache.clear();
console.log('[Cache] Cache cleared');
}
// Método para obter estatísticas do cache
getCacheStats() {
return {
size: this.cache.size,
keys: Array.from(this.cache.keys())
};
}
}
// Exemplo de uso com tratamento avançado de erros
async function exemploAvancado() {
const api = new XtreamAPIAdvanced('http://dominio_da_instancia:8080', {
maxRetries: 5,
retryDelay: 2000,
enableCache: true,
cacheTimeout: 600000 // 10 minutos
});
try {
// Tentar autenticar com retry automático
await api.authenticate('usuario_teste', 'senha123');
console.log('Autenticado com sucesso!');
// Múltiplas chamadas para testar cache
console.time('Primeira chamada');
const canais1 = await api.getLiveStreams();
console.timeEnd('Primeira chamada');
console.time('Segunda chamada (cache)');
const canais2 = await api.getLiveStreams();
console.timeEnd('Segunda chamada (cache)');
console.log('Cache stats:', api.getCacheStats());
} catch (error) {
console.error('Erro final:', error.message);
// Análise do erro
if (error.message.includes('Network Error')) {
console.error('Problema de conectividade');
} else if (error.message.includes('credentials')) {
console.error('Problema de autenticação');
} else {
console.error('Erro desconhecido');
}
}
}
exemploAvancado();
Dica: O SDK JavaScript oferece funcionalidades avançadas como cache automático, retry com backoff e prevenção de requisições duplicadas para otimizar performance.