changeset 4:c8a41359505c

server provides video listing from disk
author drewp@bigasterisk.com
date Sat, 25 Mar 2023 16:01:56 -0700
parents ee55ed10faec
children 75b54be050bc
files deploy_files.yaml deploy_ui.yaml skaffold.yaml src/VideoPage.ts src/VideoSection.ts video.py
diffstat 6 files changed, 88 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/deploy_files.yaml	Mon Mar 20 20:50:33 2023 -0700
+++ b/deploy_files.yaml	Sat Mar 25 16:01:56 2023 -0700
@@ -36,12 +36,18 @@
           command:
             - pdm
             - run
-            - python
-            - video.py
+            - uvicorn
+            - '--port=8004'
+            - '--host=0.0.0.0'
+            - '--reload'
+            - 'video:app'
           ports:
             - containerPort: 8004
           volumeMounts:
             - { name: data, mountPath: /data }
+          resources:
+            requests:
+              cpu: "2"
 
       affinity:
         nodeAffinity:
@@ -59,5 +65,6 @@
 spec:
   ports:
     - { port: 8003, targetPort: 8003, name: files }
+    - { port: 8004, targetPort: 8004, name: api }
   selector:
     app: video-files
--- a/deploy_ui.yaml	Mon Mar 20 20:50:33 2023 -0700
+++ b/deploy_ui.yaml	Sat Mar 25 16:01:56 2023 -0700
@@ -21,9 +21,6 @@
             - vite
           ports:
             - containerPort: 8002
-          # resources:
-          #   requests:
-          #     cpu: "1000m"
 ---
 apiVersion: v1
 kind: Service
@@ -31,7 +28,6 @@
   name: video
 spec:
   ports:
-    # - {port: 80, targetPort: 8000, name: py}
     - { port: 8002, targetPort: 8002, name: vite }
   selector:
     app: video
--- a/skaffold.yaml	Mon Mar 20 20:50:33 2023 -0700
+++ b/skaffold.yaml	Sat Mar 25 16:01:56 2023 -0700
@@ -9,6 +9,7 @@
       infer:
       - index.html
       - src/*
+      - '*.py'
   tagPolicy:
     dateTime:
       format: 2006-01-02_15-04-05
--- a/src/VideoPage.ts	Mon Mar 20 20:50:33 2023 -0700
+++ b/src/VideoPage.ts	Sat Mar 25 16:01:56 2023 -0700
@@ -1,14 +1,35 @@
-import { LitElement, html } from "lit";
+import { LitElement, html, css } from "lit";
 import { customElement } from "lit/decorators.js";
 export { VideoSection } from "./VideoSection";
 
+interface VideoFile {
+  webRelPath: string;
+  label: string;
+}
+
 @customElement("video-page")
 export class VideoPage extends LitElement {
+  videos: VideoFile[];
+  constructor() {
+    super();
+    this.videos = [];
+    this.loadVideos();
+  }
+  async loadVideos() {
+    const resp = await (await fetch("api/videos")).json();
+    this.videos = resp.videos as VideoFile[];
+    this.requestUpdate()
+  }
+  static styles=[css`
+
+  `]
+  // allow only 1 to play. embiggen like pbskids does.
   render() {
     return html`
       <video-section title="tl1" manifest="/tl1.webm"></video-section>
-      <video-section title="Henry Sugar" manifest="/vids/henry-sugar/manifest.mpd"></video-section>
-      <video-section title="Henry Sugar bloopers" manifest="/vids/henry-sugar-bloopers/manifest.mpd"></video-section>
+      <video-section title="Henry Sugar" manifest="files/henry-sugar/manifest.mpd"></video-section>
+      <video-section title="Henry Sugar bloopers" manifest="files/henry-sugar-bloopers/manifest.mpd"></video-section>
+      ${this.videos.map((v)=>html`<video-section title="${v.label}" manifest=${v.webRelPath}></video-section>`)}
     `;
   }
 }
--- a/src/VideoSection.ts	Mon Mar 20 20:50:33 2023 -0700
+++ b/src/VideoSection.ts	Sat Mar 25 16:01:56 2023 -0700
@@ -1,5 +1,4 @@
-
-import { LitElement, html } from "lit";
+import { LitElement, html, css } from "lit";
 import { customElement, property } from "lit/decorators.js";
 import "shaka-video-element";
 
@@ -7,20 +6,47 @@
 export class VideoSection extends LitElement {
   @property({ type: String }) manifest: string | undefined;
   @property({ type: String }) title: string = "(unknown)";
+  @property({ type: String }) big: boolean = false;
+
+  static styles = [
+    css`
+      section {
+        background: #ffffff14;
+        display: inline-block;
+        padding: 10px;
+        color: white;
+        width: 300px;
+      }
+      #video.big {
+        z-index: 2;
+        position: fixed;
+        left: 0px;
+        top: 0px;
+      }
+    `,
+  ];
   render() {
+    const vidCls = this.big ? "big" : "";
+    const inx = 20,
+      iny = 50;
+    const inw = 300,
+      inh = 150;
+    const outw = 720,
+      outh = 480;
+    const scl = outh / inh;
+    const tx = (document.body.clientWidth - inw * scl) / 2,
+      ty = (document.body.clientHeight - inh * scl) / 2;
+    const style = this.big ? `transform: translate(${-inx - inw / 2}px,${-iny - inh / 2}px) scale(${outh / inh}) translate(${tx}px,${ty}px);` : "";
+    console.log(document.body.clientWidth);
     return html`
-      <style>
-        section {
-          background: #ffffff14;
-          display: inline-block;
-          padding: 10px;
-          color: white;
-        }
-      </style>
       <section>
         <h1>${this.title}</h1>
-        <shaka-video id="video" width="720" height="480" src="${this.manifest}" controls></video>
+        <shaka-video class="${vidCls}" style="${style}" id="video" width="720" height="480" src="${this.manifest}" controls></video>
       </section>
     `;
   }
+  updated() {
+    // const  el=this.querySelector("#video")
+    // console.log(el.clientWidth);
+  }
 }
--- a/video.py	Mon Mar 20 20:50:33 2023 -0700
+++ b/video.py	Sat Mar 25 16:01:56 2023 -0700
@@ -1,14 +1,15 @@
 import asyncio
 import logging
 from typing import List
-
+from pathlib import Path
 import uvicorn
 from prometheus_client import Gauge
 from starlette.applications import Starlette
 from starlette.requests import Request
-from starlette.responses import HTMLResponse
+from starlette.responses import HTMLResponse, JSONResponse
 from starlette.routing import Route
 from starlette_exporter import PrometheusMiddleware, handle_metrics
+from video_service import findAll
 
 logging.basicConfig(level=logging.DEBUG)
 log = logging.getLogger()
@@ -18,21 +19,28 @@
     return HTMLResponse("api")
 
 
-async def main():
+def videos(req: Request) -> JSONResponse:
+    return JSONResponse({
+        "videos": [{
+            'webRelPath': vf.webRelPath,
+            'label': vf.label,
+        } for vf in findAll()]
+    })
+
+
+def main():
 
     app = Starlette(
         debug=True,
         routes=[
-            Route('/', root),
+            Route('/video/api/', root),
+            Route('/video/api/videos', videos),
         ],
     )
 
     app.add_middleware(PrometheusMiddleware, app_name='video_api')
     app.add_route("/metrics", handle_metrics)
-
-    config = uvicorn.Config(app, host='0.0.0.0', port=9053, log_level="info")
-    server = uvicorn.Server(config)
-    await server.serve()
+    return app
 
 
-asyncio.run(main(), debug=False)
+app = main()
\ No newline at end of file