summaryrefslogtreecommitdiffstats
path: root/lib/Controller/RecordingController.php
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2023-02-08 13:23:44 +0100
committerDaniel Calviño Sánchez <danxuliu@gmail.com>2023-02-22 02:41:25 +0100
commit24bb1cf20f091c83f4de4cb42984534670c7313d (patch)
tree2e33eb4bc1b4b6879a181542a5f0d6e1f4b4b47b /lib/Controller/RecordingController.php
parent7ee0f148248305fbdc3d871fb94cb6c6877c72be (diff)
Change recording status when notified by the recording server
Before the recording status was immediately changed by the Nextcloud server when a recording was started or stopped. However starting or stopping (but mostly starting) can take some time due to the initialization of the display and audio device, starting the browser, joining the call... so the recording status did not match the actual status. To address that now the recording server sends a notification back to the Nextcloud server when the recording actually started or stopped, and only then the Nextcloud server changes the recording status. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'lib/Controller/RecordingController.php')
-rw-r--r--lib/Controller/RecordingController.php103
1 files changed, 103 insertions, 0 deletions
diff --git a/lib/Controller/RecordingController.php b/lib/Controller/RecordingController.php
index a79cf2148..9cc97a29a 100644
--- a/lib/Controller/RecordingController.php
+++ b/lib/Controller/RecordingController.php
@@ -28,7 +28,10 @@ namespace OCA\Talk\Controller;
use InvalidArgumentException;
use GuzzleHttp\Exception\ConnectException;
use OCA\Talk\Config;
+use OCA\Talk\Exceptions\RoomNotFoundException;
+use OCA\Talk\Manager;
use OCA\Talk\Service\RecordingService;
+use OCA\Talk\Service\RoomService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\Http\Client\IClientService;
@@ -42,7 +45,9 @@ class RecordingController extends AEnvironmentAwareController {
private ?string $userId,
private Config $talkConfig,
private IClientService $clientService,
+ private Manager $manager,
private RecordingService $recordingService,
+ private RoomService $roomService,
private LoggerInterface $logger
) {
parent::__construct($appName, $request);
@@ -110,6 +115,104 @@ class RecordingController extends AEnvironmentAwareController {
}
/**
+ * Return the body of the backend request. This can be overridden in
+ * tests.
+ *
+ * @return string
+ */
+ protected function getInputStream(): string {
+ return file_get_contents('php://input');
+ }
+
+ /**
+ * Backend API to update recording status by backends.
+ *
+ * @PublicPage
+ * @BruteForceProtection(action=talkRecordingSecret)
+ *
+ * @return DataResponse
+ */
+ public function backend(): DataResponse {
+ $json = $this->getInputStream();
+ if (!$this->validateBackendRequest($json)) {
+ $response = new DataResponse([
+ 'type' => 'error',
+ 'error' => [
+ 'code' => 'invalid_request',
+ 'message' => 'The request could not be authenticated.',
+ ],
+ ], Http::STATUS_FORBIDDEN);
+ $response->throttle();
+ return $response;
+ }
+
+ $message = json_decode($json, true);
+ switch ($message['type'] ?? '') {
+ case 'started':
+ return $this->backendStarted($message['started']);
+ case 'stopped':
+ return $this->backendStopped($message['stopped']);
+ default:
+ return new DataResponse([
+ 'type' => 'error',
+ 'error' => [
+ 'code' => 'unknown_type',
+ 'message' => 'The given type ' . json_encode($message) . ' is not supported.',
+ ],
+ ], Http::STATUS_BAD_REQUEST);
+ }
+ }
+
+ private function backendStarted(array $started): DataResponse {
+ $token = $started['token'];
+ $status = $started['status'];
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $this->logger->debug('Failed to get room {token}', [
+ 'token' => $token,
+ 'app' => 'spreed-recording',
+ ]);
+ return new DataResponse([
+ 'type' => 'error',
+ 'error' => [
+ 'code' => 'no_such_room',
+ 'message' => 'Room not found.',
+ ],
+ ], Http::STATUS_NOT_FOUND);
+ }
+
+ $this->roomService->setCallRecording($room, $status);
+
+ return new DataResponse();
+ }
+
+ private function backendStopped(array $stopped): DataResponse {
+ $token = $stopped['token'];
+
+ try {
+ $room = $this->manager->getRoomByToken($token);
+ } catch (RoomNotFoundException $e) {
+ $this->logger->debug('Failed to get room {token}', [
+ 'token' => $token,
+ 'app' => 'spreed-recording',
+ ]);
+ return new DataResponse([
+ 'type' => 'error',
+ 'error' => [
+ 'code' => 'no_such_room',
+ 'message' => 'Room not found.',
+ ],
+ ], Http::STATUS_NOT_FOUND);
+ }
+
+ $this->roomService->setCallRecording($room);
+
+ return new DataResponse();
+ }
+
+ /**
* @NoAdminRequired
* @RequireLoggedInModeratorParticipant
*/