diff --git a/.gitignore b/.gitignore index 129d522..0c5b04d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build/bin node_modules frontend/dist +.data/* +!.data/*.ps1 \ No newline at end of file diff --git a/README.md b/README.md index 7c22430..7fb0825 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,13 @@ A 'simple' application for reading and visualizing the bitrate of media files. - [ ] Confirmation Dialogs - [ ] Localization - [ ] Logging & Log Viewer +- [ ] Stream Merging or Splitting +- [ ] GIF, Audio, Video support + +## Usage Flow + +1. Drop file +2. Select streams manually or using preset buttons + +- Drag and drop with editable stream names +- Presets reorganize streams smartly (All Together, Separate Video/Audio, All Separate, Separate Main Streams, Main Streams Only) diff --git a/app.go b/app.go index af53038..33c9c4e 100644 --- a/app.go +++ b/app.go @@ -3,24 +3,57 @@ package main import ( "context" "fmt" + + "github.com/wailsapp/wails/v2/pkg/runtime" + "gopkg.in/vansante/go-ffprobe.v2" ) // App struct type App struct { - ctx context.Context + ctx context.Context + files []File } // NewApp creates a new App application struct func NewApp() *App { - return &App{} + return &App{ + files: []File{}, + } } // startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { + runtime.OnFileDrop(ctx, func(x, y int, paths []string) { + a.OnFileDrop(x, y, paths) + }) + a.ctx = ctx } +func (a *App) shutdown(ctx context.Context) { + runtime.OnFileDropOff(ctx) +} + +func (a *App) GetStream(path string) { +} + +func (a *App) OnFileDrop(x, y int, paths []string) { + runtime.LogPrint(a.ctx, fmt.Sprintf("OnFileDrop: %v", paths)) + + for _, path := range paths { + probe, err := ffprobe.ProbeURL(a.ctx, path) + if err != nil { + runtime.LogPrint(a.ctx, fmt.Sprintf("Error: %v", err)) + continue + } + + for _, stream := range probe.Streams { + runtime.LogPrint(a.ctx, fmt.Sprintf("Stream: %v", stream)) + } + } +} + // Greet returns a greeting for the given name func (a *App) Greet(name string) string { return fmt.Sprintf("Hello %s, It's show time!", name) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a3599f9..6bc0b8d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,368 +1,139 @@ -import { useState } from "react"; -import "./App.css"; -import { Greet } from "../wailsjs/go/main/App.js"; import { ResponsiveLine } from "@nivo/line"; +import { useEffect, useMemo } from "react"; +import { OnFileDrop, OnFileDropOff } from "../wailsjs/runtime/runtime.js"; +import "./App.css"; import { formatBytes } from "./lib/format.js"; +type Frame = { + id: string; + data: { x: string | number; y: number }[]; +}; + function App() { - const [resultText, setResultText] = useState( - "Please enter your name below 👇" - ); - const [name, setName] = useState(""); - const updateName = (e: any) => setName(e.target.value); - const updateResultText = (result: string) => setResultText(result); + useEffect(() => { + OnFileDrop((_x, _y, paths) => {}, true); + return () => OnFileDropOff(); + }, []); - const data = [ - { - id: "japan", - data: [ - { - x: "plane", - y: 99, - }, - { - x: "helicopter", - y: 80, - }, - { - x: "boat", - y: 60, - }, - { - x: "train", - y: 179, - }, - { - x: "subway", - y: 102, - }, - { - x: "bus", - y: 68, - }, - { - x: "car", - y: 200, - }, - { - x: "moto", - y: 38, - }, - { - x: "bicycle", - y: 32, - }, - { - x: "horse", - y: 84, - }, - { - x: "skateboard", - y: 93, - }, - { - x: "others", - y: 206, - }, - ], - }, - { - id: "france", - data: [ - { - x: "plane", - y: 227, - }, - { - x: "helicopter", - y: 278, - }, - { - x: "boat", - y: 241, - }, - { - x: "train", - y: 104, - }, - { - x: "subway", - y: 140, - }, - { - x: "bus", - y: 16, - }, - { - x: "car", - y: 21, - }, - { - x: "moto", - y: 135, - }, - { - x: "bicycle", - y: 158, - }, - { - x: "horse", - y: 41, - }, - { - x: "skateboard", - y: 20, - }, - { - x: "others", - y: 172, - }, - ], - }, - { - id: "us", - data: [ - { - x: "plane", - y: 54, - }, - { - x: "helicopter", - y: 59, - }, - { - x: "boat", - y: 165, - }, - { - x: "train", - y: 213, - }, - { - x: "subway", - y: 79, - }, - { - x: "bus", - y: 248, - }, - { - x: "car", - y: 184, - }, - { - x: "moto", - y: 251, - }, - { - x: "bicycle", - y: 122, - }, - { - x: "horse", - y: 12, - }, - { - x: "skateboard", - y: 269, - }, - { - x: "others", - y: 101, - }, - ], - }, - { - id: "germany", - data: [ - { - x: "plane", - y: 177, - }, - { - x: "helicopter", - y: 249, - }, - { - x: "boat", - y: 37, - }, - { - x: "train", - y: 173, - }, - { - x: "subway", - y: 145, - }, - { - x: "bus", - y: 283, - }, - { - x: "car", - y: 50, - }, - { - x: "moto", - y: 231, - }, - { - x: "bicycle", - y: 100, - }, - { - x: "horse", - y: 226, - }, - { - x: "skateboard", - y: 5, - }, - { - x: "others", - y: 139, - }, - ], - }, - { - id: "norway", - data: [ - { - x: "plane", - y: 234, - }, - { - x: "helicopter", - y: 38, - }, - { - x: "boat", - y: 254, - }, - { - x: "train", - y: 228, - }, - { - x: "subway", - y: 106, - }, - { - x: "bus", - y: 213, - }, - { - x: "car", - y: 289, - }, - { - x: "moto", - y: 116, - }, - { - x: "bicycle", - y: 272, - }, - { - x: "horse", - y: 50, - }, - { - x: "skateboard", - y: 263, - }, - { - x: "others", - y: 196, - }, - ], - }, - ]; + const data: Frame[] = []; + // const data: Frame[] = useMemo(() => + // // Array.from({ length: 4 }, (_, i) => { + // // const d = Math.random(); + // // const g = Math.random(); + // // return { + // // id: `file-${i}`, + // // data: Array.from({ length: 500 }, (_, j) => { + // // if (Math.random() < 0.5) return null; + // // return { + // // x: j, + // // y: Math.random() * 256 * d + (1 - g) * 1024, + // // }; + // // }).filter((i) => i !== null), + // // }; + // // }), + // [] + // ); - function greet() { - Greet(name).then(updateResultText); - } + console.log(data); - return ( -