Files
terebi/Makefile
T
hl-valdemar 230949bb95 feat: add a native CLI launcher for local and YouTube playback
Build .build/terebi beside the app. Parse a single local file or YouTube URL, --url, --, and help; reject invalid commands before GUI launch. Resolve the adjacent app through symlinks and launch through NSWorkspace, reusing its process/window and saved progress.

Launch the app without media before delivering URL events. Raw media argv suppress SwiftUI's initial singleton window. Own warm document and internet Apple events because SwiftUI's default external-event routing closes that window; retain initial Finder document delivery to create it.

Verified actual CLI 0/64/69 exit behavior, PATH/symlink discovery from another directory, cold local/YouTube playback, warm local/YouTube replacement in the same native window/process, resume, Finder-style cold launch, and make all check.
2026-10-11 00:45:24 +02:00

109 lines
7.7 KiB
Makefile

CXX := xcrun clang++
SWIFT := xcrun swiftc
FFMPEG := libavformat libavcodec libavutil libswresample libswscale
FF_CFLAGS := $(shell pkg-config --cflags $(FFMPEG))
FF_LIBS := $(shell pkg-config --libs $(FFMPEG))
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
SWIFT_SOURCES := Sources/App/TerebiApp.swift Sources/App/CompactWindow.swift Sources/App/YouTubeResolver.swift Sources/App/PlaybackProgress.swift
APP := .build/terebi.app
.PHONY: all run check check-fixtures check-audio check-window check-youtube check-network check-progress check-cli
all: .build/terebi $(APP)/Contents/Info.plist
.build:
mkdir -p $@
.build/player.o: Sources/Core/player.cpp Sources/Core/player.h Sources/Core/player_macos.h Sources/Core/output.hpp Sources/Core/network_input.hpp Makefile | .build
$(CXX) $(CXXFLAGS) -c $< -o $@
.build/Output.o: Sources/macOS/Output.mm Sources/Core/output.hpp Makefile | .build
$(CXX) $(CXXFLAGS) -fobjc-arc -c $< -o $@
$(APP)/Contents/MacOS/terebi: $(SWIFT_SOURCES) $(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 $(SWIFT_SOURCES) $(OBJECTS) $(FF_LIBS) $(FRAMEWORKS) -lc++ -o $@
$(APP)/Contents/Info.plist: Resources/Info.plist
mkdir -p $(APP)/Contents
cp $< $@
.build/terebi: Sources/CLI/TerebiCLI.swift Sources/CLI/PlayerCommand.swift Sources/App/YouTubeResolver.swift $(APP)/Contents/MacOS/terebi $(APP)/Contents/Info.plist Makefile
rm -f $@
$(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g Sources/CLI/TerebiCLI.swift Sources/CLI/PlayerCommand.swift Sources/App/YouTubeResolver.swift -framework AppKit -o $@
run: all
open $(APP)
.build/playback-check: Checks/playback.mm $(OBJECTS) Makefile
$(CXX) $(CXXFLAGS) -fobjc-arc $< $(OBJECTS) $(FF_LIBS) $(FRAMEWORKS) -o $@
check: .build/playback-check check-fixtures check-audio check-window check-youtube check-network check-progress check-cli
.build/playback-check .build/fixtures
check-fixtures:
mkdir -p .build/fixtures
ffmpeg -hide_banner -loglevel error -y -f lavfi -i testsrc2=size=320x180:rate=24 -f lavfi -i sine=frequency=440:sample_rate=44100 -t 4 -c:v mpeg4 -bf 2 -c:a aac .build/fixtures/av.mp4
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/av.mp4 -an -c:v copy .build/fixtures/video.mp4
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/av.mp4 -an -vf setsar=3/2 -c:v mpeg4 .build/fixtures/anamorphic.mp4
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/av.mp4 -vn -c:a pcm_s16le .build/fixtures/audio.wav
# Literal frame PTS: 0,.1,.2,.3,.4,.65,.9,1.15,1.4,1.5,1.6,1.7; reordered B-frames across short GOPs.
ffmpeg -hide_banner -loglevel error -y -f lavfi -i testsrc2=size=320x180:rate=10:duration=1.2 -f lavfi -i sine=frequency=440:sample_rate=44100:duration=2 -vf "settb=1/1000,setpts='if(lt(N,5),N*100,if(lt(N,9),400+(N-4)*250,1400+(N-8)*100))'" -fps_mode vfr -enc_time_base:v 1:1000 -c:v mpeg4 -g 4 -bf 2 -video_track_timescale 1000 -c:a aac .build/fixtures/frame-step.mp4
ffmpeg -hide_banner -loglevel error -y -f lavfi -i testsrc2=size=160x90:rate=12 -t 1 -vf 'format=yuv420p10le,setparams=color_primaries=bt2020:color_trc=smpte2084:colorspace=bt2020nc' -c:v ffv1 .build/fixtures/hdr.mkv
.build/Output-check.o: Sources/macOS/Output.mm Sources/Core/output.hpp Makefile | .build
$(CXX) $(CXXFLAGS) -fobjc-arc -DPLAYER_AUDIO_CHECK -c $< -o $@
.build/audio-continuity-check: Checks/audio-continuity.cpp .build/player.o .build/Output-check.o Makefile
$(CXX) $(CXXFLAGS) $< .build/player.o .build/Output-check.o $(FF_LIBS) $(FRAMEWORKS) -o $@
check-audio: .build/audio-continuity-check
mkdir -p .build/fixtures
ffmpeg -hide_banner -loglevel error -y -f lavfi -i sine=frequency=440:sample_rate=44100 -t 2 -c:a pcm_s16le .build/fixtures/tone441.wav
ffmpeg -hide_banner -loglevel error -y -f lavfi -i sine=frequency=440:sample_rate=48000 -t 2 -c:a pcm_s16le .build/fixtures/tone480.wav
ffmpeg -hide_banner -loglevel error -y -f lavfi -i testsrc2=size=160x90:rate=24:duration=2 -i .build/fixtures/tone480.wav -c:v mpeg4 -g 48 -bf 2 -c:a copy .build/fixtures/tone-step.mov
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone441.wav -c:a copy .build/fixtures/tone441.mka
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone441.wav -c:a aac .build/fixtures/tone-aac.m4a
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone441.wav -af "asetpts='PTS+gte(T,1)*0.25/TB'" -c:a pcm_s16le .build/fixtures/tone-gap.mka
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone441.wav -ar 48000 -ac 2 -f f32le .build/fixtures/tone441.wav.f32
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone480.wav -ar 48000 -ac 2 -f f32le .build/fixtures/tone480.wav.f32
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone441.mka -ar 48000 -ac 2 -f f32le .build/fixtures/tone441.mka.f32
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/tone-aac.m4a -ar 48000 -ac 2 -f f32le .build/fixtures/tone-aac.m4a.f32
.build/audio-continuity-check .build/fixtures
.build/compact-window-check: Checks/compact-window.swift Sources/App/CompactWindow.swift Makefile | .build
$(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g Checks/compact-window.swift Sources/App/CompactWindow.swift -framework AppKit -o $@
check-window: .build/compact-window-check
.build/compact-window-check
.build/youtube-resolver-check: Checks/youtube-resolver.swift Sources/App/YouTubeResolver.swift Makefile | .build
$(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g Checks/youtube-resolver.swift Sources/App/YouTubeResolver.swift -framework Foundation -o $@
check-youtube: .build/youtube-resolver-check
.build/youtube-resolver-check
.build/network-playback-check: Checks/network-playback.mm $(OBJECTS) Makefile
$(CXX) $(CXXFLAGS) -fobjc-arc $< $(OBJECTS) $(FF_LIBS) $(FRAMEWORKS) -o $@
check-network: .build/network-playback-check check-fixtures
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/frame-step.mp4 -an -c:v copy .build/fixtures/frame-step-video.mp4
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/frame-step.mp4 -vn -c:a copy .build/fixtures/frame-step-audio.m4a
ffmpeg -hide_banner -loglevel error -y -f lavfi -i testsrc2=size=320x180:rate=24 -f lavfi -i sine=frequency=440:sample_rate=44100 -t 30 -c:v mpeg4 -q:v 2 -bf 2 -c:a aac -movflags +faststart .build/fixtures/streaming.mp4
ffmpeg -hide_banner -loglevel error -y -i .build/fixtures/av.mp4 -c:v libx264 -g 24 -keyint_min 24 -sc_threshold 0 -c:a aac -hls_time 1 -hls_playlist_type vod -hls_segment_filename .build/fixtures/network-vod-%d.ts .build/fixtures/network-vod.m3u8
python3 Checks/streaming.py .build/network-playback-check .build/fixtures
.build/playback-progress-check: Checks/playback-progress.swift Sources/App/PlaybackProgress.swift Makefile | .build
$(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g Checks/playback-progress.swift Sources/App/PlaybackProgress.swift -framework Foundation -o $@
check-progress: .build/playback-progress-check
.build/playback-progress-check
.build/player-command-check: Checks/player-command.swift Sources/CLI/PlayerCommand.swift Sources/App/YouTubeResolver.swift Makefile | .build
$(SWIFT) -target $(ARCH)-apple-macosx15.0 -swift-version 6 -parse-as-library -O -g Checks/player-command.swift Sources/CLI/PlayerCommand.swift Sources/App/YouTubeResolver.swift -framework Foundation -o $@
check-cli: .build/player-command-check
.build/player-command-check