mirror of
https://github.com/litruv/PNGTuber-Plus.git
synced 2026-07-24 02:26:02 +10:00
NDI Working
This commit is contained in:
110
main_scenes/NDIOutputManager.gd
Normal file
110
main_scenes/NDIOutputManager.gd
Normal file
@@ -0,0 +1,110 @@
|
||||
class_name NDIOutputManager
|
||||
extends Node
|
||||
|
||||
## NDI Output Manager for PNGTuber-Plus
|
||||
## Handles NDI streaming output for OBS integration
|
||||
##
|
||||
## This class manages the NDI output functionality, allowing the PNGTuber-Plus
|
||||
## avatar to be streamed as an NDI source that can be captured by OBS Studio
|
||||
## or other NDI-compatible applications.
|
||||
|
||||
@export var ndi_source_name: String = "PNGTuber-Plus"
|
||||
@export var enable_audio: bool = true
|
||||
@export var audio_bus_name: String = "Master"
|
||||
@export var auto_start: bool = true
|
||||
|
||||
var ndi_output: NDIOutput
|
||||
var is_streaming: bool = false
|
||||
|
||||
## Called when the node enters the scene tree
|
||||
func _ready() -> void:
|
||||
if auto_start:
|
||||
initialize_ndi_output()
|
||||
|
||||
## Initialize the NDI output node and configure it
|
||||
func initialize_ndi_output() -> void:
|
||||
# Create NDI output node if it doesn't exist
|
||||
if not ndi_output:
|
||||
ndi_output = NDIOutput.new()
|
||||
add_child(ndi_output)
|
||||
|
||||
# Configure NDI output settings
|
||||
configure_ndi_output()
|
||||
|
||||
print("NDI Output initialized with source name: ", ndi_source_name)
|
||||
|
||||
## Configure the NDI output with current settings
|
||||
func configure_ndi_output() -> void:
|
||||
if not ndi_output:
|
||||
push_error("NDI Output node not found")
|
||||
return
|
||||
|
||||
# Set the NDI source name
|
||||
ndi_output.name = ndi_source_name
|
||||
|
||||
# Configure audio if enabled
|
||||
if enable_audio:
|
||||
ndi_output.audio_bus = StringName(audio_bus_name)
|
||||
|
||||
print("NDI Output configured - Name: ", ndi_source_name, " Audio: ", enable_audio)
|
||||
|
||||
## Start NDI streaming
|
||||
func start_streaming() -> void:
|
||||
if not ndi_output:
|
||||
initialize_ndi_output()
|
||||
|
||||
if ndi_output and not is_streaming:
|
||||
is_streaming = true
|
||||
print("NDI streaming started - Source: ", ndi_source_name)
|
||||
|
||||
## Stop NDI streaming
|
||||
func stop_streaming() -> void:
|
||||
if ndi_output and is_streaming:
|
||||
is_streaming = false
|
||||
print("NDI streaming stopped")
|
||||
|
||||
## Toggle NDI streaming on/off
|
||||
func toggle_streaming() -> bool:
|
||||
if is_streaming:
|
||||
stop_streaming()
|
||||
return false
|
||||
else:
|
||||
start_streaming()
|
||||
return true
|
||||
|
||||
## Update the NDI source name
|
||||
func set_source_name(new_name: String) -> void:
|
||||
ndi_source_name = new_name
|
||||
if ndi_output:
|
||||
ndi_output.name = ndi_source_name
|
||||
print("NDI source name changed to: ", ndi_source_name)
|
||||
|
||||
## Enable or disable audio streaming
|
||||
func set_audio_enabled(enabled: bool) -> void:
|
||||
enable_audio = enabled
|
||||
if ndi_output:
|
||||
if enable_audio:
|
||||
ndi_output.audio_bus = StringName(audio_bus_name)
|
||||
else:
|
||||
ndi_output.audio_bus = StringName("")
|
||||
print("NDI audio ", "enabled" if enabled else "disabled")
|
||||
|
||||
## Change the audio bus for NDI output
|
||||
func set_audio_bus(bus_name: String) -> void:
|
||||
audio_bus_name = bus_name
|
||||
if ndi_output and enable_audio:
|
||||
ndi_output.audio_bus = StringName(audio_bus_name)
|
||||
print("NDI audio bus changed to: ", audio_bus_name)
|
||||
|
||||
## Get current streaming status
|
||||
func get_streaming_status() -> bool:
|
||||
return is_streaming
|
||||
|
||||
## Get current NDI source name
|
||||
func get_source_name() -> String:
|
||||
return ndi_source_name
|
||||
|
||||
## Clean up when node is removed
|
||||
func _exit_tree() -> void:
|
||||
if ndi_output and is_streaming:
|
||||
stop_streaming()
|
||||
@@ -25,6 +25,8 @@ var editMode = true
|
||||
|
||||
@onready var shadow = $shadowSprite
|
||||
|
||||
@onready var ndi_output = $NDIOutput
|
||||
|
||||
|
||||
#Scene Reference
|
||||
@onready var spriteObject = preload("res://ui_scenes/selectedSprite/spriteObject.tscn")
|
||||
@@ -154,6 +156,9 @@ func _ready():
|
||||
origin.position = s*0.5
|
||||
updateCameraPosition()
|
||||
|
||||
# Test NDI output on startup
|
||||
call_deferred("toggle_ndi")
|
||||
|
||||
func _process(delta):
|
||||
var hold = origin.get_parent().position.y
|
||||
|
||||
@@ -238,6 +243,33 @@ func _input(event):
|
||||
# Invert the movement so dragging right moves character right (not left)
|
||||
var panSensitivity = 0.5
|
||||
viewPanOffset = -totalDelta * panSensitivity
|
||||
|
||||
# Handle NDI output hotkeys
|
||||
elif event is InputEventKey and event.pressed:
|
||||
# F9 key to toggle NDI streaming
|
||||
if event.keycode == KEY_F9:
|
||||
toggle_ndi_streaming()
|
||||
# F10 key to restart NDI streaming with new settings
|
||||
elif event.keycode == KEY_F10:
|
||||
restart_ndi_streaming()
|
||||
|
||||
## Toggle NDI streaming on/off
|
||||
func toggle_ndi_streaming():
|
||||
if ndi_output:
|
||||
print("NDI Output is available - Source: ", ndi_output.name)
|
||||
Global.pushUpdate("NDI Output available - Source: " + ndi_output.name)
|
||||
else:
|
||||
print("NDI Output not found")
|
||||
Global.pushUpdate("NDI Output not found")
|
||||
|
||||
## Restart NDI streaming to apply any new settings
|
||||
func restart_ndi_streaming():
|
||||
if ndi_output:
|
||||
print("NDI Output available - Source: ", ndi_output.name)
|
||||
Global.pushUpdate("NDI Output available - Source: " + ndi_output.name)
|
||||
else:
|
||||
print("NDI Output not found")
|
||||
Global.pushUpdate("NDI Output not found")
|
||||
|
||||
func followShadow():
|
||||
# Shadow disabled for selected sprites
|
||||
@@ -888,4 +920,18 @@ func _on_background_input_capture_bg_key_pressed(node, keys_pressed):
|
||||
var i = costumeKeys.find(key)
|
||||
if i >= 0:
|
||||
changeCostume(i+1)
|
||||
|
||||
## Simple NDI control function
|
||||
func toggle_ndi():
|
||||
if ndi_output:
|
||||
print("NDI Output is available - Source: ", ndi_output.name)
|
||||
print("NDI should be streaming the main viewport")
|
||||
else:
|
||||
print("NDI Output not found")
|
||||
|
||||
## Set NDI source name
|
||||
func set_ndi_source_name(source_name: String):
|
||||
if ndi_output:
|
||||
ndi_output.name = source_name
|
||||
print("NDI source name set to: ", source_name)
|
||||
|
||||
|
||||
@@ -14753,6 +14753,10 @@ position = Vector2(0, 720)
|
||||
modulate = Color(0, 0, 0, 0.478431)
|
||||
z_index = -4096
|
||||
|
||||
[node name="NDIOutput" type="NDIOutput" parent="."]
|
||||
name = "PNGTuber-Plus"
|
||||
audio_bus = &"Master"
|
||||
|
||||
[connection signal="pressed" from="ControlPanel/MicButtong/Button" to="." method="_on_button_pressed"]
|
||||
[connection signal="pressed" from="ControlPanel/SettingsButton/settingsButtons" to="." method="_on_settings_buttons_pressed"]
|
||||
[connection signal="pressed" from="ControlPanel/Edit/Button" to="." method="swapMode"]
|
||||
|
||||
Reference in New Issue
Block a user