rsvg scrive su .tmp poi rename; il feeder ignora PNG parziali. YouTube relay: no doppio avvio, reconnect RTMP; overlay restart solo dopo 3 miss. Co-authored-by: Cursor <cursoragent@cursor.com>
44 lines
1.2 KiB
Ruby
44 lines
1.2 KiB
Ruby
#!/usr/bin/env ruby
|
|
# Invia overlay.png aggiornata a ffmpeg via image2pipe (FIFO).
|
|
# ffmpeg con -loop 1 legge il file una sola volta: questo processo rilegge il PNG
|
|
# quando cambia mtime (punteggio, badge stato, …).
|
|
require "fileutils"
|
|
|
|
pipe_path = ARGV.fetch(0)
|
|
png_path = ARGV.fetch(1)
|
|
poll_sec = (ARGV[2] || ENV.fetch("OVERLAY_PIPE_POLL_SEC", "0.4")).to_f
|
|
|
|
abort "pipe mancante: #{pipe_path}" unless File.exist?(pipe_path)
|
|
abort "png mancante: #{png_path}" unless File.exist?(png_path)
|
|
|
|
stop = false
|
|
trap("TERM") { stop = true }
|
|
trap("INT") { stop = true }
|
|
|
|
# image2pipe richiede frame continui: inviamo la PNG a ritmo fisso ( anche se invariata ).
|
|
last_bytes = nil
|
|
File.open(pipe_path, "wb") do |pipe|
|
|
loop do
|
|
break if stop
|
|
|
|
if File.exist?(png_path)
|
|
bytes = File.binread(png_path)
|
|
# Evita frame corrotti durante rsvg-convert (file parziale prima del rename atomico).
|
|
next if bytes.bytesize < 512
|
|
|
|
if bytes != last_bytes
|
|
pipe.write(bytes)
|
|
pipe.flush
|
|
last_bytes = bytes
|
|
elsif last_bytes
|
|
pipe.write(last_bytes)
|
|
pipe.flush
|
|
end
|
|
end
|
|
|
|
sleep poll_sec
|
|
end
|
|
rescue Errno::EPIPE
|
|
# ffmpeg chiuso
|
|
end
|