diff --git a/lib/Controller/VideoController.php b/lib/Controller/VideoController.php index 9f43bd39..0ed4a023 100644 --- a/lib/Controller/VideoController.php +++ b/lib/Controller/VideoController.php @@ -35,8 +35,6 @@ class VideoController extends ApiBase * @NoCSRFRequired * * Transcode a video to HLS by proxy - * - * @return JSONResponse an empty JSONResponse with respective http status code */ public function transcode(string $client, string $fileid, string $profile): Http\Response { @@ -137,6 +135,41 @@ class VideoController extends ApiBase return $response; } + /** + * @NoAdminRequired + * + * @NoCSRFRequired + * + * Return the live video part of a live photo + */ + public function livephoto(string $fileid) + { + $fileid = (int) $fileid; + $files = $this->rootFolder->getById($fileid); + if (0 === \count($files)) { + return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); + } + $file = $files[0]; + + // Check file etag + $etag = $file->getEtag(); + if ($etag !== $this->request->getParam('etag')) { + return new JSONResponse(['message' => 'File changed'], Http::STATUS_PRECONDITION_FAILED); + } + + // Check file liveid + $liveid = $this->request->getParam('liveid'); + if (!$liveid) { + return new JSONResponse(['message' => 'Live ID not provided'], Http::STATUS_BAD_REQUEST); + } + $lp = $this->timelineQuery->getLivePhoto($fileid); + if (!$lp || $lp['liveid'] !== $liveid) { + return new JSONResponse(['message' => 'Live ID not found'], Http::STATUS_NOT_FOUND); + } + + return new JSONResponse($lp); + } + private function getUpstream($client, $path, $profile) { $path = rawurlencode($path); diff --git a/lib/Db/TimelineQuery.php b/lib/Db/TimelineQuery.php index 54d33574..e5a23ec0 100644 --- a/lib/Db/TimelineQuery.php +++ b/lib/Db/TimelineQuery.php @@ -14,6 +14,7 @@ class TimelineQuery use TimelineQueryFaces; use TimelineQueryFilters; use TimelineQueryFolders; + use TimelineQueryLivePhoto; use TimelineQueryTags; protected IDBConnection $connection; diff --git a/lib/Db/TimelineQueryDays.php b/lib/Db/TimelineQueryDays.php index d1f58ffc..b52b01d5 100644 --- a/lib/Db/TimelineQueryDays.php +++ b/lib/Db/TimelineQueryDays.php @@ -152,7 +152,7 @@ trait TimelineQueryDays // We don't actually use m.datetaken here, but postgres // needs that all fields in ORDER BY are also in SELECT // when using DISTINCT on selected fields - $query->select($fileid, 'm.isvideo', 'm.video_duration', 'm.datetaken', 'm.dayid', 'm.w', 'm.h') + $query->select($fileid, 'm.isvideo', 'm.video_duration', 'm.datetaken', 'm.dayid', 'm.w', 'm.h', 'm.liveid') ->from('memories', 'm') ; @@ -282,6 +282,9 @@ trait TimelineQueryDays $row['isfavorite'] = 1; } unset($row['categoryid']); + if (!$row['liveid']) { + unset($row['liveid']); + } // Check if path exists and starts with basePath and remove if (isset($row['path']) && !empty($row['path'])) { diff --git a/lib/Db/TimelineQueryLivePhoto.php b/lib/Db/TimelineQueryLivePhoto.php new file mode 100644 index 00000000..bd28f542 --- /dev/null +++ b/lib/Db/TimelineQueryLivePhoto.php @@ -0,0 +1,25 @@ +connection->getQueryBuilder(); + $qb->select('lp.fileid', 'lp.liveid') + ->from('memories', 'm') + ->where($qb->expr()->eq('m.fileid', $qb->createNamedParameter($fileid))) + ->innerJoin('m', 'memories_livephoto', 'lp', $qb->expr()->andX( + $qb->expr()->eq('lp.liveid', 'm.liveid'), + )) + ; + $result = $qb->executeQuery(); + $row = $result->fetch(); + $result->closeCursor(); + + return $row; + } +}