Homepage redesign, ep38 publish, Castopod fix, share icons, avatar gender
Website: - Full homepage redesign: new hero with punchy tagline, social proof strip with real caller quotes, featured episode spotlight, clips moved up - Remove Q&A section, cover art from hero, secondary links - Fix share icon fill (currentColor), add .sr-only class - Bump cache versions to v=6 Backend: - Blacklist Celeste voice - Fix avatar gender caching with marker files - Fix _match_voices_to_styles() bypassing BLACKLISTED_VOICES Publishing: - Fix Castopod container path (/var/www/castopod/ → /app/) - Revert CLOUDFLARE_UPLOAD_LIMIT workaround (API fixed) - Publish episode 38 Reaper: - Dual silence threshold (2.5s transitions, 6s same-speaker) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
-- Show Region Marker — background script for REAPER
|
||||
-- Polls /tmp/reaper_state.txt for state changes and creates colored regions.
|
||||
-- Backend writes "dialog", "ad", or "ident" to the file.
|
||||
-- Run via Actions → Run ReaScript before or during recording.
|
||||
|
||||
local STATE_FILE = "/tmp/reaper_state.txt"
|
||||
|
||||
local COLORS = {
|
||||
dialog = reaper.ColorToNative(50, 180, 50) + 0x1000000, -- green
|
||||
ad = reaper.ColorToNative(200, 80, 80) + 0x1000000, -- red
|
||||
ident = reaper.ColorToNative(80, 120, 200) + 0x1000000, -- blue
|
||||
}
|
||||
local LABELS = {
|
||||
dialog = "DIALOG",
|
||||
ad = "AD",
|
||||
ident = "IDENT",
|
||||
}
|
||||
|
||||
local counts = { dialog = 0, ad = 0, ident = 0 }
|
||||
local current_type = nil -- which region type is currently open
|
||||
local current_start = 0
|
||||
local last_pos = 0 -- last known transport position (while running)
|
||||
local last_state = ""
|
||||
local transport_active = false
|
||||
|
||||
local function log(msg)
|
||||
reaper.ShowConsoleMsg("[Regions] " .. msg .. "\n")
|
||||
end
|
||||
|
||||
local function is_playing_or_recording()
|
||||
local state = reaper.GetPlayState()
|
||||
return state > 0 and state ~= 2
|
||||
end
|
||||
|
||||
local function open_region(rtype)
|
||||
if current_type then return end
|
||||
current_type = rtype
|
||||
current_start = reaper.GetPlayPosition()
|
||||
log("OPEN " .. rtype .. " at " .. string.format("%.2f", current_start))
|
||||
end
|
||||
|
||||
local function close_region(pos_override)
|
||||
if not current_type then return end
|
||||
local pos = pos_override or reaper.GetPlayPosition()
|
||||
local len = pos - current_start
|
||||
local rtype = current_type
|
||||
current_type = nil
|
||||
log("CLOSE " .. rtype .. " at " .. string.format("%.2f", pos) .. " (len=" .. string.format("%.2f", len) .. ")")
|
||||
if len > 0.1 then
|
||||
counts[rtype] = counts[rtype] + 1
|
||||
local name = LABELS[rtype] .. " " .. counts[rtype]
|
||||
reaper.AddProjectMarker2(0, true, current_start, pos, name, -1, COLORS[rtype])
|
||||
log(" -> Created '" .. name .. "'")
|
||||
else
|
||||
log(" -> Skipped (too short)")
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
if not transport_active then
|
||||
if is_playing_or_recording() then
|
||||
transport_active = true
|
||||
log("Transport started at " .. string.format("%.2f", reaper.GetPlayPosition()))
|
||||
local f = io.open(STATE_FILE, "r")
|
||||
if f then
|
||||
last_state = f:read("*l") or "dialog"
|
||||
f:close()
|
||||
else
|
||||
last_state = "dialog"
|
||||
end
|
||||
log("Initial state: '" .. last_state .. "'")
|
||||
open_region(last_state)
|
||||
end
|
||||
reaper.defer(poll)
|
||||
return
|
||||
end
|
||||
|
||||
-- Track position while transport is running
|
||||
last_pos = reaper.GetPlayPosition()
|
||||
|
||||
-- Detect transport stop (recording ended) — use last known good position
|
||||
if not is_playing_or_recording() then
|
||||
log("Transport stopped at last known pos " .. string.format("%.2f", last_pos))
|
||||
close_region(last_pos)
|
||||
transport_active = false
|
||||
reaper.defer(poll)
|
||||
return
|
||||
end
|
||||
|
||||
local f = io.open(STATE_FILE, "r")
|
||||
if f then
|
||||
local state = f:read("*l") or "dialog"
|
||||
f:close()
|
||||
|
||||
if state ~= last_state then
|
||||
log("State change: '" .. last_state .. "' -> '" .. state .. "'")
|
||||
close_region()
|
||||
open_region(state)
|
||||
last_state = state
|
||||
end
|
||||
end
|
||||
|
||||
reaper.defer(poll)
|
||||
end
|
||||
|
||||
log("Script loaded — waiting for transport to start...")
|
||||
|
||||
reaper.atexit(function()
|
||||
log("Script stopping (atexit)")
|
||||
close_region()
|
||||
local total = counts.dialog + counts.ad + counts.ident
|
||||
log("Done. " .. total .. " regions (" .. counts.dialog .. " dialog, " .. counts.ad .. " ad, " .. counts.ident .. " ident)")
|
||||
end)
|
||||
|
||||
poll()
|
||||
Reference in New Issue
Block a user