← लैब पर वापस

macOS पर --headless के बिना Godot Movie Maker और स्क्रीनशॉट

godotapple-siliconguide

मैं चाहता था कि Godot मेरे Mac पर किसी स्क्रिप्ट से स्क्रीनशॉट और छोटे वीडियो लिखे, जैसे Linux पर CI में करता है। macOS 26.5.2 पर Godot 4.7.1 यह --headless में नहीं कर पाता, लेकिन असली रेंडरर और स्क्रीन से बाहर रखी विंडो के साथ कर लेता है। एक बात मैं हल नहीं कर पाया: चलते समय ऐप फिर भी सामने आ जाता है।

--headless की त्रुटि और स्क्रीन से बाहर रखी विंडो के साथ लिखे गए एक Movie Maker रन के चार फ़्रेम (फ़्रेम 0, 16, 32 और 47)

नीचे सब कुछ एक 640 × 360 वाले टेस्ट प्रोजेक्ट पर चला, जिसमें एक ही स्क्रिप्ट है:

extends Node2D
 
# Saves the 30th frame to the path given after "--" and quits.
var frames := 0
 
func _process(_delta: float) -> void:
	$Box.position.x = 80.0 + frames * 4.0
	frames += 1
	var args := OS.get_cmdline_user_args()
	if frames == 30 and args.size() > 0:
		await RenderingServer.frame_post_draw
		get_viewport().get_texture().get_image().save_png(args[0])
		get_tree().quit()

कैप्चर करते समय --headless क्या करता है

Godot.app/Contents/MacOS/Godot --headless --path . -- "$PWD/out.png"

स्क्रिप्ट फ़्रेम 30 तक पहुँची और फिर await RenderingServer.frame_post_draw पर हमेशा के लिए रुक गई: 15 सेकंड बाद भी प्रोसेस चल रही थी, और कुछ भी सेव नहीं हुआ। await के बिना टेक्सचर पढ़ने पर यह तुरंत विफल हो जाता है:

ERROR: Parameter "t" is null.
   at: texture_2d_get (./servers/rendering/dummy/storage/texture_storage.h:110)

--headless में Godot एक डमी रेंडरर पर चलता है, इसलिए व्यूपोर्ट के पास पढ़ने के लिए कोई टेक्सचर नहीं होता; त्रुटि में दिया पाथ उसी डमी रेंडरर का टेक्सचर स्टोरेज है। Linux पर आम तरीका असली रेंडरर के नीचे एक वर्चुअल X डिस्प्ले लगाना है। Godot का macOS बिल्ड macOS के विंडो सर्वर और Metal से ड्रॉ करता है, इसलिए यह तरीका Mac पर काम नहीं आता।

असली रेंडरिंग, स्क्रीन से बाहर

असली रेंडरर रहने दें और विंडो को रास्ते से हटा दें। विंडो की सेटिंग्स विंडो बनते समय लागू होती हैं, किसी भी स्क्रिप्ट के चलने से पहले, इसलिए रन के दौरान वे project.godot के बगल में override.cfg में रहती हैं:

[display]
 
window/size/no_focus=true
window/size/initial_position_type=0
window/size/initial_position=Vector2i(-6000, -6000)
window/size/always_on_top=false

फिर ऐप को open से शुरू करें:

open -n -W -g -j -a Godot.app --stdout run.log --stderr run.log \
  --args --path "$PWD" -- "$PWD/out.png"
rm override.cfg

-n Godot के पहले से खुले होने पर भी नया इंस्टेंस शुरू करता है, -W उसके बंद होने तक इंतज़ार करता है, -g उसे बैकग्राउंड में रखता है, -j उसे छिपाकर शुरू करता है, और --stdout व --stderr उसका आउटपुट फ़ाइल में लौटाते हैं। इनके बिना open आउटपुट फेंक देता है, क्योंकि Godot आपके शेल की चाइल्ड प्रोसेस नहीं है। फ़्रेम 640 × 360 में और सीन के अपने रंगों में लौटा: औसत RGB 188, 117, 82, यानी नारंगी बैकग्राउंड पर नीला बॉक्स।

रन खत्म होने पर override.cfg मिटा दें। Godot हर लॉन्च पर इसे पढ़ता है, इसलिए rm से पहले बीच में रुका रन अगले सामान्य लॉन्च के लिए ऐसी विंडो छोड़ जाता है जिसे कभी कीबोर्ड फ़ोकस नहीं मिलता।

Movie Maker: PNG सीक्वेंस, फिर MP4

Movie Maker हर फ़्रेम एक तय दर से रेंडर करता है, इसलिए वीडियो की टाइमिंग इस पर निर्भर नहीं करती कि मशीन कितनी तेज़ी से रेंडर करती है:

open -n -W -g -j -a Godot.app --stdout run.log --stderr run.log \
  --args --path "$PWD" --write-movie "$PWD/movie/f.png" --fixed-fps 24 --quit-after 48
48 frames at 24 FPS (movie length: 00:00:02:00), recorded in 00:00:01 (200% of real-time speed).

इसने f00000000.png से f00000047.png तक लिखे, और ऑडियो उनके बगल में f.wav के रूप में। ffmpeg फ़्रेमों से वीडियो बनाता है:

ffmpeg -framerate 24 -i movie/f%08d.png -c:v libx264 -pix_fmt yuv420p -crf 18 film.mp4

नतीजा 24 fps पर 48 फ़्रेम था, 2.0 सेकंड लंबा।

हल नहीं हुआ: फ़ोकस

no_focus विंडो को कीबोर्ड फ़ोकस लेने से रोकता है, लेकिन Godot विंडो खोलते समय फिर भी खुद को सक्रिय ऐप बना देता है। दो रन के दौरान मैंने बार-बार देखा कि सबसे आगे कौन-सा ऐप है। एक फ़्रेम वाले रन में Godot 21 में से 1 सैंपल में आगे था, और Movie Maker वाले रन में, जिसमें लगभग एक सेकंड लगा, लगातार 4 सैंपल में; हर बार Godot के बंद होने पर वह ऐप फिर आगे आ गया जिसमें मैं काम कर रहा था। सितंबर में LSUIElement को true करके बनाई गई ऐप बंडल की कॉपी से भी मदद नहीं मिली। लंबी रिकॉर्डिंग में Godot कितनी देर आगे रहता है, यह मैंने नहीं मापा।

सीमाएँ