From 681a7be6f7103983bfb9d83dd9d924ae535efb60 Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Sat, 10 Oct 2026 19:25:52 +0200 Subject: [PATCH] chore: rename project and app to terebi --- Makefile | 6 +++--- README.md | 6 +++--- Resources/Info.plist | 6 +++--- Sources/App/{PlayerApp.swift => TerebiApp.swift} | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) rename Sources/App/{PlayerApp.swift => TerebiApp.swift} (99%) diff --git a/Makefile b/Makefile index 5c5f189..018383e 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,10 @@ ARCH := $(shell uname -m) CXXFLAGS := -std=c++20 -mmacosx-version-min=15.0 -O2 -g -Wall -Wextra -Wno-unused-parameter $(FF_CFLAGS) FRAMEWORKS := -framework AppKit -framework AudioToolbox -framework CoreAudio -framework Metal -framework MetalKit -framework QuartzCore OBJECTS := .build/player.o .build/Output.o -APP := .build/Player.app +APP := .build/terebi.app .PHONY: all run check check-audio -all: $(APP)/Contents/MacOS/Player $(APP)/Contents/Info.plist +all: $(APP)/Contents/MacOS/terebi $(APP)/Contents/Info.plist .build: mkdir -p $@ @@ -21,7 +21,7 @@ all: $(APP)/Contents/MacOS/Player $(APP)/Contents/Info.plist .build/Output.o: Sources/macOS/Output.mm Sources/Core/output.hpp Makefile | .build $(CXX) $(CXXFLAGS) -fobjc-arc -c $< -o $@ -$(APP)/Contents/MacOS/Player: Sources/App/PlayerApp.swift $(OBJECTS) Makefile +$(APP)/Contents/MacOS/terebi: Sources/App/TerebiApp.swift $(OBJECTS) Makefile mkdir -p $(APP)/Contents/MacOS $(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g -import-objc-header Sources/Core/player_macos.h $< $(OBJECTS) $(FF_LIBS) $(FRAMEWORKS) -lc++ -o $@ diff --git a/README.md b/README.md index 4a11f0f..2b5e42b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Player +# terebi A personal native macOS player whose playback code is small enough to own and modify. FFmpeg reads and decodes media; our C++ worker owns playback. SwiftUI owns the controls, Core Audio owns audio output, and Metal presents video. @@ -12,7 +12,7 @@ make make run ``` -The local app is `.build/Player.app`. It links the installed FFmpeg libraries; it is not a standalone distributable bundle. After upgrading FFmpeg, rebuild with `make -B`. +The local app is `.build/terebi.app`. It links the installed FFmpeg libraries; it is not a standalone distributable bundle. After upgrading FFmpeg, rebuild with `make -B`. Open a local file with **⌘O**, drop it onto the window, or use Finder's **Open With**. Successfully opened files start playback automatically, including when replacing the current file. **⇧⌘W** closes the file; closing the window quits and joins the worker. @@ -49,7 +49,7 @@ Only implemented actions have controls; there are no placeholder playlist, subti - `Sources/Core/player.h`: the C interface and authoritative state snapshot. Playback commands enqueue work; poll state for completion. `seek_pending` is set synchronously when a seek or frame step is accepted and clears when all queued seeks/steps on that timeline finish. `player_step_frame` accepts only `-1` or `+1`, requires ready video, and publishes the selected frame's timestamp as `position`. Volume set/get is synchronous and uses a lock-free target gain. Callers own the opaque handle and must stop using it before destruction. - `Sources/Core/player.cpp`: single demux/decode worker, bounded buffers, timestamps, audio-master synchronization, paused previews, exact frame stepping, decoder/resampler drain, seeking, errors, and shutdown. A seek stops output and flushes all old timeline state before resuming. - `Sources/Core/output.hpp` and `Sources/macOS/Output.mm`: native output contract, allocation-free/nonblocking Core Audio callback and bounded audio ring, latency-aware presentation clock, retained frame mailbox, and Metal YUV conversion. The view can outlive the player safely. -- `Sources/App/PlayerApp.swift`: MainActor state polling, file panel/Finder/drop handling, autoplay, video host, AppKit glass and native slider cells, floating controls, visibility, video-fitted sizing, and native window integration. The shared `PlayerModel.open` path enqueues play after an accepted open, on the new file's command timeline; the C interface still opens paused for callers that need explicit playback control. +- `Sources/App/TerebiApp.swift`: MainActor state polling, file panel/Finder/drop handling, autoplay, video host, AppKit glass and native slider cells, floating controls, visibility, video-fitted sizing, and native window integration. The shared `PlayerModel.open` path enqueues play after an accepted open, on the new file's command timeline; the C interface still opens paused for callers that need explicit playback control. - `Makefile`: compiler/linker commands and app bundle construction. No generated Xcode project or additional build dependency. ## Runnable check diff --git a/Resources/Info.plist b/Resources/Info.plist index 58d7fcf..52e2074 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -2,9 +2,9 @@ - CFBundleExecutablePlayer - CFBundleIdentifierlocal.personal.player - CFBundleNamePlayer + CFBundleExecutableterebi + CFBundleIdentifierlocal.personal.terebi + CFBundleNameterebi CFBundlePackageTypeAPPL CFBundleShortVersionString0.1 LSMinimumSystemVersion15.0 diff --git a/Sources/App/PlayerApp.swift b/Sources/App/TerebiApp.swift similarity index 99% rename from Sources/App/PlayerApp.swift rename to Sources/App/TerebiApp.swift index 811bc40..5a0c151 100644 --- a/Sources/App/PlayerApp.swift +++ b/Sources/App/TerebiApp.swift @@ -139,7 +139,7 @@ final class PlayerModel: ObservableObject { isSeeking = false seekPending = false window?.representedURL = nil - window?.title = "Player" + window?.title = "terebi" revealControls() } @@ -179,7 +179,7 @@ final class PlayerModel: ObservableObject { func attachWindow(_ window: NSWindow) { self.window = window - window.title = fileName ?? "Player" + window.title = fileName ?? "terebi" updateWindowState() fitVideoWindow() } @@ -451,11 +451,11 @@ private struct PlayerContent: View { } else { Image(systemName: "play.rectangle.fill").font(.system(size: 14)) } - Text(model.fileName ?? "Player") + Text(model.fileName ?? "terebi") .font(.system(size: 13, weight: .semibold)) .lineLimit(1) .truncationMode(.middle) - .help(model.fileName ?? "Player") + .help(model.fileName ?? "terebi") Spacer(minLength: 12) iconButton(model.isOnTop ? "pin.fill" : "pin", model.isOnTop ? "Stop Keeping Window on Top" : "Keep Window on Top", action: model.toggleOnTop) @@ -601,7 +601,7 @@ private struct PlayerContent: View { VStack(spacing: 14) { Image(systemName: "play.rectangle").font(.system(size: 56, weight: .ultraLight)) .foregroundStyle(.white.opacity(0.65)) - Text("Player").font(.system(size: 22, weight: .medium)) + Text("terebi").font(.system(size: 22, weight: .medium)) Text("Drop a media file here").font(.callout).foregroundStyle(.secondary) Button("Open File…", action: model.openPanel) .buttonStyle(.bordered).controlSize(.large).disabled(!model.canOpen) @@ -808,12 +808,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate { @main @MainActor -struct PlayerApp: App { +struct TerebiApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) private var delegate @StateObject private var model = PlayerModel.shared var body: some Scene { - Window("\(model.fileName ?? "Player")", id: "player") { + Window("\(model.fileName ?? "terebi")", id: "terebi") { PlayerContent(model: model) } .defaultSize(width: 900, height: 560)