Files
vibedit/main.go
Sean MTS c6ac7d2222 Initial commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:28:47 +00:00

94 lines
2.7 KiB
Go

// VibEdit is a small video cutter: it splits clips out of source videos and
// joins them back together using ffmpeg. The UI is a local web page served by
// this program and opened in an Edge/Chrome app window.
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
const appName = "VibEdit"
var version = "1.0.0"
func main() {
addr := flag.String("addr", "127.0.0.1:0", "address to listen on")
noBrowser := flag.Bool("no-browser", false, "do not open the editor window automatically")
defaultBrowser := flag.Bool("default-browser", false, "open in the default web browser instead of an Edge/Chrome app window")
ffmpegPath := flag.String("ffmpeg", "", "path to ffmpeg (default: next to this program, then PATH)")
ffprobePath := flag.String("ffprobe", "", "path to ffprobe (default: next to this program, then PATH)")
keepAlive := flag.Bool("keep-alive", false, "keep running after the editor window is closed")
flag.Parse()
log.SetFlags(log.Ltime)
fmt.Printf("%s %s - simple ffmpeg video cutter\n\n", appName, version)
app := newApp(*ffmpegPath, *ffprobePath, *keepAlive)
if !app.tools.OK() {
fmt.Println("WARNING: ffmpeg/ffprobe not found.")
fmt.Println(" Put ffmpeg" + exeSuffix + " and ffprobe" + exeSuffix + " in the same folder as this program")
fmt.Println(" (or on your PATH). Windows builds: https://www.gyan.dev/ffmpeg/builds/")
fmt.Println()
} else {
fmt.Printf("ffmpeg: %s\nffprobe: %s\n\n", app.tools.FFmpeg, app.tools.FFprobe)
}
ln, err := net.Listen("tcp", *addr)
if err != nil {
fatal("Could not start the local web server: %v", err)
}
tcp := ln.Addr().(*net.TCPAddr)
host := tcp.IP.String()
if tcp.IP.IsUnspecified() {
host = "127.0.0.1"
}
hostPort := net.JoinHostPort(host, fmt.Sprint(tcp.Port))
app.configureHost(tcp)
url := fmt.Sprintf("http://%s/?t=%s", hostPort, app.token)
fmt.Println("Editor address (open this if no window appears):")
fmt.Println(" " + url)
fmt.Println()
fmt.Println("Close the editor window or this console to quit.")
fmt.Println()
if !*noBrowser {
go func() {
if err := openBrowser(url, *defaultBrowser); err != nil {
log.Printf("could not open a browser: %v", err)
}
}()
}
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
go func() {
<-sig
app.requestQuit("interrupted")
}()
srv := &http.Server{Handler: app, ReadHeaderTimeout: 10 * time.Second}
go func() {
<-app.quit
srv.Close()
}()
if err := srv.Serve(ln); err != nil && err != http.ErrServerClosed {
fatal("Web server stopped: %v", err)
}
app.shutdown()
}
func fatal(format string, args ...any) {
fmt.Fprintf(os.Stderr, "\nERROR: "+format+"\n", args...)
waitBeforeExit()
os.Exit(1)
}