36896-vm/api.php
Flatlogic Bot 48cd368984 cloud
2025-12-12 17:05:57 +00:00

263 lines
11 KiB
PHP

<?php
header('Content-Type: application/json');
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/db/config.php';
$response = [];
$action = $_GET['action'] ?? '';
use Dropbox\Client;
use Dropbox\Exception;
switch ($action) {
case 'save':
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$url = $data['url'] ?? null;
$filename = $data['filename'] ?? null;
$token = $data['token'] ?? null;
if (empty($url) || empty($filename)) {
http_response_code(400);
$response['error'] = 'URL do stream e nome do arquivo são obrigatórios.';
} elseif (!filter_var($url, FILTER_VALIDATE_URL)) {
http_response_code(400);
$response['error'] = 'URL do stream inválida.';
} else {
try {
$pdo = db();
$stmt = $pdo->prepare(
"INSERT INTO streams (url, filename, dropbox_token, status) VALUES (:url, :filename, :token, 'pending')"
);
$stmt->execute([
':url' => $url,
':filename' => $filename,
':token' => $token
]);
$newId = $pdo->lastInsertId();
http_response_code(201);
$response['success'] = true;
$response['message'] = 'Stream salvo com sucesso! Pronto para conversão.';
$response['job_id'] = $newId;
} catch (PDOException $e) {
http_response_code(500);
$response['error'] = 'Erro no banco de dados: ' . $e->getMessage();
}
}
} else {
http_response_code(405);
$response['error'] = 'Método não permitido para esta ação.';
}
break;
case 'get_streams':
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, url, filename, status, created_at FROM streams ORDER BY created_at DESC");
$streams = $stmt->fetchAll(PDO::FETCH_ASSOC);
$response['success'] = true;
$response['streams'] = $streams;
} catch (PDOException $e) {
http_response_code(500);
$response['error'] = 'Erro no banco de dados: ' . $e->getMessage();
}
break;
case 'convert_to_mp4':
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$id = $data['id'] ?? null;
if (empty($id)) {
http_response_code(400);
$response['error'] = 'O ID do stream é obrigatório.';
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT url, filename FROM streams WHERE id = :id");
$stmt->execute([':id' => $id]);
$stream = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$stream) {
http_response_code(404);
$response['error'] = 'Stream não encontrado.';
} else {
$pdo->prepare("UPDATE streams SET status = 'converting' WHERE id = :id")->execute([':id' => $id]);
$output_filename = pathinfo($stream['filename'], PATHINFO_FILENAME) . '_' . time() . '.mp4';
$output_path = __DIR__ . '/videos/' . $output_filename;
if (!is_dir(__DIR__ . '/videos')) {
mkdir(__DIR__ . '/videos', 0775, true);
}
$command = [
'ffmpeg',
'-i', $stream['url'],
'-c:v', 'libx264',
'-preset', 'veryfast',
'-crf', '23',
'-c:a', 'aac',
'-b:a', '128k',
$output_path
];
$process = new \Symfony\Component\Process\Process($command);
$process->setTimeout(3600);
$process->run();
if (!$process->isSuccessful()) {
http_response_code(500);
$error_output = $process->getErrorOutput();
$pdo->prepare("UPDATE streams SET status = 'error', error_message = :error WHERE id = :id")->execute([':error' => $error_output, ':id' => $id]);
$response['error'] = 'Falha na conversão do vídeo.';
} else {
$stmt = $pdo->prepare("UPDATE streams SET status = 'completed', converted_path = :converted_path WHERE id = :id");
$stmt->execute([
':converted_path' => $output_filename,
':id' => $id
]);
$response['success'] = true;
$response['message'] = 'Vídeo convertido com sucesso!';
}
}
} catch (PDOException $e) {
http_response_code(500);
$response['error'] = 'Erro no banco de dados: ' . $e->getMessage();
} catch (\Exception $e) {
http_response_code(500);
$response['error'] = 'Erro na conversão: ' . $e->getMessage();
}
}
} else {
http_response_code(405);
$response['error'] = 'Método não permitido para esta ação.';
}
break;
case 'send_to_dropbox':
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$id = $data['id'] ?? null;
$token = $data['token'] ?? null;
if (empty($id) || empty($token)) {
http_response_code(400);
$response['error'] = 'O ID do stream e o token do Dropbox são obrigatórios.';
break;
}
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT converted_path FROM streams WHERE id = :id AND status = 'completed'");
$stmt->execute([':id' => $id]);
$stream = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$stream || empty($stream['converted_path'])) {
http_response_code(404);
$response['error'] = 'Arquivo convertido não encontrado ou o stream não está completo.';
break;
}
$filePath = __DIR__ . '/videos/' . $stream['converted_path'];
if (!file_exists($filePath)) {
http_response_code(404);
$response['error'] = 'Arquivo físico não encontrado no servidor.';
break;
}
/*
COMO OBTER UM TOKEN DE ACESSO DO DROPBOX:
1. Vá para https://www.dropbox.com/developers/apps e clique em "Create app".
2. Escolha "Scoped Access".
3. Selecione "Full Dropbox" ou "App folder".
4. Dê um nome único à sua aplicação (ex: MeuConversorDeVideo).
5. Na aba "Permissions", marque as permissões: `files.content.write`.
6. Clique em "Submit".
7. Na aba "Settings", procure pela seção "Generated access token" e clique em "Generate".
8. Copie o token gerado e cole no campo "Token do Dropbox" na interface.
*/
$app = new \Dropbox\App("", "", $token);
$dropbox = new \Dropbox\Client($app);
$dropboxFileName = '/' . basename($filePath);
$file = $dropbox->upload($filePath, $dropboxFileName, ['autorename' => true]);
$response['success'] = true;
$response['message'] = 'Arquivo enviado com sucesso para o Dropbox!';
$response['file_name'] = $file->getName();
} catch (PDOException $e) {
http_response_code(500);
$response['error'] = 'Erro no banco de dados: ' . $e->getMessage();
} catch (\Dropbox\Exception $e) {
http_response_code(500);
$response['error'] = 'Erro no Dropbox: ' . $e->getMessage();
} catch (Exception $e) {
http_response_code(500);
$response['error'] = 'Ocorreu um erro inesperado: ' . $e->getMessage();
}
} else {
http_response_code(405);
$response['error'] = 'Método não permitido para esta ação.';
}
break;
default:
http_response_code(400);
$response['error'] = 'Ação não especificada ou inválida.';
break;
case 'delete':
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$id = $data['id'] ?? null;
if (empty($id)) {
http_response_code(400);
$response['error'] = 'O ID do stream é obrigatório.';
break;
}
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT converted_path FROM streams WHERE id = :id");
$stmt->execute([':id' => $id]);
$stream = $stmt->fetch(PDO::FETCH_ASSOC);
if ($stream && !empty($stream['converted_path'])) {
$filePath = __DIR__ . '/videos/' . $stream['converted_path'];
if (file_exists($filePath)) {
unlink($filePath);
}
}
$stmt = $pdo->prepare("DELETE FROM streams WHERE id = :id");
$stmt->execute([':id' => $id]);
if ($stmt->rowCount() > 0) {
$response['success'] = true;
$response['message'] = 'Vídeo e registro apagados com sucesso!';
} else {
http_response_code(404);
$response['error'] = 'Nenhum vídeo encontrado com este ID.';
}
} catch (PDOException $e) {
http_response_code(500);
$response['error'] = 'Erro no banco de dados: ' . $e->getMessage();
} catch (\Exception $e) {
http_response_code(500);
$response['error'] = 'Ocorreu um erro inesperado: ' . $e->getMessage();
}
} else {
http_response_code(405);
$response['error'] = 'Método não permitido para esta ação.';
}
break;
}
echo json_encode($response);