chore: rename project and app to terebi

This commit is contained in:
2026-10-10 19:25:52 +02:00
parent 33858bd8ce
commit 681a7be6f7
4 changed files with 16 additions and 16 deletions
+3 -3
View File
@@ -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 $@
+3 -3
View File
@@ -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
+3 -3
View File
@@ -2,9 +2,9 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key><string>Player</string>
<key>CFBundleIdentifier</key><string>local.personal.player</string>
<key>CFBundleName</key><string>Player</string>
<key>CFBundleExecutable</key><string>terebi</string>
<key>CFBundleIdentifier</key><string>local.personal.terebi</string>
<key>CFBundleName</key><string>terebi</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleShortVersionString</key><string>0.1</string>
<key>LSMinimumSystemVersion</key><string>15.0</string>
@@ -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)