From 44de53ad7a6966a8453f2729ef92c254a5542868 Mon Sep 17 00:00:00 2001 From: gsd Date: Sun, 1 Sep 2024 21:22:09 +0300 Subject: [PATCH] preview order --- backend/assets/loading.webp | Bin 0 -> 8134 bytes backend/config_parser.py | 7 ++++++ backend/server.py | 21 ++++++++++-------- .../app/components/about/about.component.ts | 4 +++- .../components/history/history.component.html | 3 +-- frontend/ang_dvrip/src/app/utils/BaseUtils.ts | 4 ++++ 6 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 backend/assets/loading.webp diff --git a/backend/assets/loading.webp b/backend/assets/loading.webp new file mode 100644 index 0000000000000000000000000000000000000000..a8da92d0c78f96a920c7483b0788541f321e9255 GIT binary patch literal 8134 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 DF6j49 literal 0 HcmV?d00001 diff --git a/backend/config_parser.py b/backend/config_parser.py index fe2c42b..0b35559 100644 --- a/backend/config_parser.py +++ b/backend/config_parser.py @@ -150,6 +150,7 @@ class Go2Rtc: class TranscodeTools: statuses:dict[str, TranscodeStatus] = {} WIN32PYTHON = "python-win32" + preview_storage = [] def __init__(self, tools_directory, transcode_directory, hide_checks = True, delete_temporary_files = False) -> None: self.delete_temporary_files = delete_temporary_files @@ -279,6 +280,12 @@ class TranscodeTools: async def processing_preview(self, file:File, nvr: NVR, ext = "webp", preview_pre_bytes = 1024 * 512): raw_file = file.previewPath(self.transcode_directory) preview_file = f"{raw_file}.{ext}" + + if preview_file in self.preview_storage: + return preview_file + else: + self.preview_storage.append(preview_file) + if os.path.exists(preview_file) and os.path.getsize(preview_file) != 0: self.logger.info(f"{preview_file} is exists") return preview_file diff --git a/backend/server.py b/backend/server.py index caf8e97..6e557cc 100644 --- a/backend/server.py +++ b/backend/server.py @@ -228,7 +228,7 @@ class Server: response.status_code = 400 return {"ok":False, "error":e} @self.app.get(self.API_BASE_REF + "/preview/{recorder_index}") - async def getTranscodePreview(response: Response, recorder_index:int, b64:str): + async def getTranscodePreview(response: Response, recorder_index:int, b64:str, background_tasks: BackgroundTasks): try: if len(b64) == 0: response.status_code = 404 @@ -236,17 +236,20 @@ class Server: file: File = File.from_b64(b64 + "==") - try: - preview = await self.config.transcode_tools.processing_preview(file, None, "webp") - except NeedNVR: + async def loadPreview(file): nvr:NVR = self.config.getRecorder(recorder_index).nvr await nvr.login() - preview = await self.config.transcode_tools.processing_preview(file, nvr, "webp") + await self.config.transcode_tools.processing_preview(file, nvr, "webp") - headers = {} - headers.update({"Content-Length":str(os.path.getsize(preview))}) - headers.update({"Content-Disposition": f'attachment; filename="preview.webp"'}) - return FileResponse(preview, media_type="application/octet-stream", headers=headers) + try: + preview = await self.config.transcode_tools.processing_preview(file, None, "webp") + headers = {} + headers.update({"Content-Length":str(os.path.getsize(preview))}) + headers.update({"Content-Disposition": f'attachment; filename="preview.webp"'}) + return FileResponse(preview, media_type="application/octet-stream", headers=headers) + except NeedNVR: + background_tasks.add_task(loadPreview, file = file) + return FileResponse("./assets/loading.webp") except Exception as e: traceback.print_exc() diff --git a/frontend/ang_dvrip/src/app/components/about/about.component.ts b/frontend/ang_dvrip/src/app/components/about/about.component.ts index b99f93f..ae195ad 100644 --- a/frontend/ang_dvrip/src/app/components/about/about.component.ts +++ b/frontend/ang_dvrip/src/app/components/about/about.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import {ActivatedRoute} from "@angular/router"; +import {BaseUtils} from "../../utils/BaseUtils"; @Component({ selector: 'app-about', @@ -11,6 +12,7 @@ export class AboutComponent implements OnInit { channel_index: number = 0; img: string = ""; updated: Date = new Date(); + baseUtils = BaseUtils; constructor(private route:ActivatedRoute) {} @@ -21,7 +23,7 @@ export class AboutComponent implements OnInit { } getSnapshot() { - this.img = `/api/dvrip/snapshot/${this.recorder_index}/${this.channel_index}?timestamp=${new Date().getTime()}` + this.img = `/api/dvrip/snapshot/${this.recorder_index}/${this.channel_index}?timestamp=${this.baseUtils.getTime()}` this.updated = new Date(); } diff --git a/frontend/ang_dvrip/src/app/components/history/history.component.html b/frontend/ang_dvrip/src/app/components/history/history.component.html index f4b9867..0f75c79 100644 --- a/frontend/ang_dvrip/src/app/components/history/history.component.html +++ b/frontend/ang_dvrip/src/app/components/history/history.component.html @@ -35,7 +35,7 @@ mat-card-image style="cursor: pointer" (click)="openTransCodeDialog(element)" - [src]="'api/dvrip/preview/'+recorder_index+'?b64='+element.b64" + [src]="'api/dvrip/preview/'+recorder_index+'?b64='+element.b64+'×tamp='+this.baseUtils.getTime()" alt="Превью недоступно"> @@ -48,7 +48,6 @@ > {{element.processing != null?'cloud_upload':element.converted?'cloud_done':'cloud_download'}} {{element.processing != null?'Обработка':element.converted?'Просмотреть':'Загрузить'}} - diff --git a/frontend/ang_dvrip/src/app/utils/BaseUtils.ts b/frontend/ang_dvrip/src/app/utils/BaseUtils.ts index fe86b25..b3e364d 100644 --- a/frontend/ang_dvrip/src/app/utils/BaseUtils.ts +++ b/frontend/ang_dvrip/src/app/utils/BaseUtils.ts @@ -25,4 +25,8 @@ export class BaseUtils { return new Date(); } } + + static getTime():number { + return new Date().getTime(); + } }