Bläddra i källkod

show videos with bitrate

Joystream Stats 2 år sedan
förälder
incheckning
fdd36077fa
5 ändrade filer med 111 tillägg och 5 borttagningar
  1. 1 1
      src/App.tsx
  2. 14 3
      src/components/Dashboard/index.tsx
  3. 86 0
      src/components/Media/index.tsx
  4. 8 0
      src/components/Media/index.tsx~
  5. 2 1
      src/state.ts

+ 1 - 1
src/App.tsx

@@ -396,7 +396,7 @@ class App extends React.Component<IProps, IState> {
 
   async loadData() {
     console.debug(`Loading data`);
-    "status members assets providers councils council election workers categories channels proposals posts threads openings tokenomics transactions reports validators nominators staches stakes rewardPoints stars blocks hidden"
+    "status members assets providers councils council election workers categories channels proposals posts threads openings tokenomics transactions reports validators nominators staches stakes rewardPoints stars blocks hidden media"
       .split(" ")
       .map((key) => this.load(key));
     getTokenomics().then((tokenomics) => this.save(`tokenomics`, tokenomics));

+ 14 - 3
src/components/Dashboard/index.tsx

@@ -1,12 +1,23 @@
-import Events from '../Events'
+import Events from "../Events";
+import Media from "../Media";
 
 interface IProps extends IState {
   blocks: { id: number; events: any }[];
 }
 
 const Dashboard = (props: IProps) => {
-  const { save, hidden, selectEvent, blocks} = props
-  return <Events save={save} hidden={hidden} selectEvent={selectEvent} blocks={blocks} />
+  const { save, media, hidden, selectEvent, blocks } = props;
+  return (
+    <>
+      <Media save={save} media={media} />
+      <Events
+        save={save}
+        hidden={hidden}
+        selectEvent={selectEvent}
+        blocks={blocks}
+      />
+    </>
+  );
 };
 
 export default Dashboard;

+ 86 - 0
src/components/Media/index.tsx

@@ -0,0 +1,86 @@
+import { useEffect } from "react";
+import { Badge } from "react-bootstrap";
+import axios from "axios";
+import { queryNode } from "../../config";
+
+const query = `query {
+  storageBags { id
+    distributionBuckets { operators { metadata{nodeEndpoint } } }
+    objects { id size  
+      videoMedia {id categoryId isCensored     isExplicit    isFeatured isPublic
+        thumbnailPhotoId duration title description
+        mediaMetadata {pixelWidth pixelHeight size encoding {codecName}}
+      }
+    }
+  }
+}`;
+
+const Media = (props: {}) => {
+  const { save, media } = props;
+
+  useEffect(() => {
+    media?.storageBags?.length ||
+      axios
+        .post(queryNode, { query })
+        .then(({ data }) => save("media", data.data))
+        .catch((e) => console.error(query, e.message));
+  }, [media?.storageBags?.length]);
+
+  return (
+    <div className="box">
+      <h2>Media</h2>
+      {media.storageBags?.length ? (
+        <div className="d-flex flex-wrap">
+          {media.storageBags
+            .reduce((objects, b) => {
+              b.objects.map((o) =>
+                objects.push({
+                  ...o,
+                  providers: b.distributionBuckets,
+                  bitrate: o.videoMedia?.duration
+                    ? (o.size / o.videoMedia.duration).toFixed()
+                    : 0,
+                })
+              );
+              return objects;
+            }, [])
+            .filter((o) => o.bitrate)
+            .sort((a, b) => b.bitrate - a.bitrate)
+            .map((o) => (
+              <Video key={o.id} {...o} />
+            ))}
+        </div>
+      ) : (
+        ""
+      )}
+    </div>
+  );
+};
+
+const Video = (props: {}) => {
+  const { id, title, videoMedia, bitrate, providers, size } = props;
+  const alt = `${id} ${videoMedia.title}`;
+  if (!providers?.length) return "";
+  const url = providers[0].operators[0].metadata.nodeEndpoint;
+  return (
+    <div
+      key={videoMedia.id}
+      className="text-left m-1"
+      style={{ width: "200px" }}
+    >
+      <img
+        className="d-block"
+        style={{ width: "200px" }}
+        src={url + "api/v1/assets/" + videoMedia.thumbnailPhotoId}
+        alt={alt}
+        title={alt}
+      />
+      <div>
+        {(bitrate / 1024 ** 2).toFixed(2)} mps / {(size / 1024 ** 2).toFixed()}
+        MB / {videoMedia.duration}s
+      </div>
+    </div>
+  );
+};
+
+export default Media;

+ 8 - 0
src/components/Media/index.tsx~

@@ -0,0 +1,8 @@
+import {useEffect, useState} from "react"
+import axios from "axios"
+
+const Media = () => {
+return "some media"
+}
+
+export default Media

+ 2 - 1
src/state.ts

@@ -29,7 +29,7 @@ export const initialState = {
   stashes: [],
   stars: {},
   hideFooter: true,
-  hidden: ['ExtrinsicSuccess'],
+  hidden: ["ExtrinsicSuccess"],
   syncEvents: false,
   showStatus: false,
   editKpi: false,
@@ -41,4 +41,5 @@ export const initialState = {
     eraTotals: {},
     validators: {},
   },
+  media: {},
 };