263 lines
11 KiB
PHP
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);
|