switch to two voip addon

This commit is contained in:
Nordup 2025-09-15 17:30:54 +07:00
parent cf11ceffc4
commit 9ce4caa073
39 changed files with 193 additions and 52 deletions

View file

@ -19,5 +19,5 @@ It has: <br/>
## Credits ## Credits
* Platformer Kit (2.2) - https://www.kenney.nl (CC0) * Platformer Kit (2.2) - https://www.kenney.nl (CC0)
* VoIP extension for Godot 4 - https://github.com/RevoluPowered/one-voip-godot-4 (MIT) * VoIP extension for Godot 4 - https://github.com/goatchurchprime/two-voip-godot-4 (MIT)
* RoboBlast: Third-Person Shooter demo - https://github.com/gdquest-demos/godot-4-3d-third-person-controller (MIT and CC-By 4.0) * RoboBlast: Third-Person Shooter demo - https://github.com/gdquest-demos/godot-4-3d-third-person-controller (MIT and CC-By 4.0)

View file

@ -1,15 +0,0 @@
[configuration]
entry_symbol = "one_voip_library_init"
compatibility_minimum = 4.2
[libraries]
windows.release.x86_64="libonevoip.windows.template_debug.x86_64.dll"
windows.debug.x86_64="libonevoip.windows.template_debug.x86_64.dll"
linux.release.x86_64="libonevoip.linux.template_debug.x86_64.so"
linux.debug.x86_64="libonevoip.linux.template_debug.x86_64.so"
macos.release.x86_64="exports/welcome_page/libonevoip.macos.template_debug.universal.dylib"
macos.debug.x86_64="exports/welcome_page/libonevoip.macos.template_debug.universal.dylib"
macos.release.arm64="exports/welcome_page/libonevoip.macos.template_debug.universal.dylib"
macos.debug.arm64="exports/welcome_page/libonevoip.macos.template_debug.universal.dylib"

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>libtwovoip.macos.template_debug.universal.dylib</string>
<key>CFBundleName</key>
<string>TwoVoIP</string>
<key>CFBundleDisplayName</key>
<string>TwoVoIP</string>
<key>CFBundleIdentifier</key>
<string>ru.dmitriysalnikov.twovoip</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) Dmitriy Salnikov.</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTPlatformName</key>
<string>macosx</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
</dict>
</plist>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>libtwovoip.macos.template_release.universal.dylib</string>
<key>CFBundleName</key>
<string>TwoVoIP</string>
<key>CFBundleDisplayName</key>
<string>TwoVoIP</string>
<key>CFBundleIdentifier</key>
<string>ru.dmitriysalnikov.twovoip</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) Dmitriy Salnikov.</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTPlatformName</key>
<string>macosx</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
</dict>
</plist>

View file

@ -0,0 +1,79 @@
[configuration]
entry_symbol = "two_voip_library_init"
compatibility_minimum = "4.1.4"
reloadable = false
[dependencies]
; example.x86_64 = { "relative or absolute path to the dependency" : "the path relative to the exported project", }
; -------------------------------------
; debug
macos = { }
windows.x86_64 = { }
linux.x86_64 = { }
; by default godot is using threads
web.wasm32.nothreads = {}
web.wasm32 = {}
android.arm32 = { }
android.arm64 = { }
android.x86_32 = { }
android.x86_64 = { }
ios = {}
; -------------------------------------
; release
macos.template_release = { }
windows.template_release.x86_64 = { }
linux.template_release.x86_64 = { }
web.template_release.wasm32.nothreads = { }
web.template_release.wasm32 = { }
android.template_release.arm32 = { }
android.template_release.arm64 = { }
android.template_release.x86_32 = { }
android.template_release.x86_64 = { }
ios.template_release = {}
[libraries]
; -------------------------------------
; debug
macos = "libs/libtwovoip.macos.template_debug.universal.framework"
windows.x86_64 = "libs/libtwovoip.windows.template_debug.x86_64.dll"
linux.x86_64 = "libs/libtwovoip.linux.template_debug.x86_64.so"
web.wasm32.nothreads = "libs/libtwovoip.web.template_debug.wasm32.wasm"
web.wasm32 = "libs/libtwovoip.web.template_debug.wasm32.threads.wasm"
android.arm32 = "libs/libtwovoip.android.template_debug.arm32.so"
android.arm64 = "libs/libtwovoip.android.template_debug.arm64.so"
android.x86_32 = "libs/libtwovoip.android.template_debug.x86_32.so"
android.x86_64 = "libs/libtwovoip.android.template_debug.x86_64.so"
ios = "libs/libtwovoip.ios.template_debug.universal.dylib"
; -------------------------------------
; release
macos.template_release = "libs/libtwovoip.macos.template_release.universal.framework"
windows.template_release.x86_64 = "libs/libtwovoip.windows.template_release.x86_64.dll"
linux.template_release.x86_64 = "libs/libtwovoip.linux.template_release.x86_64.so"
web.template_release.wasm32.nothreads = "libs/libtwovoip.web.template_release.wasm32.wasm"
web.template_release.wasm32 = "libs/libtwovoip.web.template_release.wasm32.threads.wasm"
android.template_release.arm32 = "libs/libtwovoip.android.template_release.arm32.so"
android.template_release.arm64 = "libs/libtwovoip.android.template_release.arm64.so"
android.template_release.x86_32 = "libs/libtwovoip.android.template_release.x86_32.so"
android.template_release.x86_64 = "libs/libtwovoip.android.template_release.x86_64.so"
ios.template_release = "libs/libtwovoip.ios.template_release.universal.dylib"

View file

@ -4,8 +4,8 @@
resource_name = "Amplify" resource_name = "Amplify"
volume_db = 6.0 volume_db = 6.0
[sub_resource type="VOIPInputCapture" id="VOIPInputCapture_gsvqe"] [sub_resource type="AudioEffectOpusChunked" id="AudioEffectOpusChunked_yv5ll"]
resource_name = "VOIPInputCapture" resource_name = "OpusChunked"
[resource] [resource]
bus/1/name = &"Character" bus/1/name = &"Character"
@ -28,5 +28,5 @@ bus/3/mute = true
bus/3/bypass_fx = false bus/3/bypass_fx = false
bus/3/volume_db = 0.0 bus/3/volume_db = 0.0
bus/3/send = &"Master" bus/3/send = &"Master"
bus/3/effect/0/effect = SubResource("VOIPInputCapture_gsvqe") bus/3/effect/0/effect = SubResource("AudioEffectOpusChunked_yv5ll")
bus/3/effect/0/enabled = true bus/3/effect/0/enabled = true

View file

@ -1,10 +1,8 @@
class_name CameraController class_name CameraController
extends Node3D extends Node3D
@export_node_path var player_path : NodePath
@export var invert_mouse_y := false @export var invert_mouse_y := false
@export_range(0.0, 1.0) var mouse_sensitivity := 0.25 @export_range(0.0, 1.0) var mouse_sensitivity := 0.25
@export_range(0.0, 8.0) var joystick_sensitivity := 2.0
@export var tilt_upper_limit := deg_to_rad(-60.0) @export var tilt_upper_limit := deg_to_rad(-60.0)
@export var tilt_lower_limit := deg_to_rad(60.0) @export var tilt_lower_limit := deg_to_rad(60.0)

View file

@ -1,7 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://dh42cdejchkr3"] [gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://dh42cdejchkr3"]
[ext_resource type="Shader" path="res://player/model/materials/face_mat.gdshader" id="1_u8nh3"] [ext_resource type="Shader" path="res://player/model/materials/face_mat.gdshader" id="1_u8nh3"]
[ext_resource type="Texture2D" uid="uid://ci7cn145ld3l5" path="res://player/model/faces/closed.png" id="2_r4pvf"] [ext_resource type="Texture2D" uid="uid://dbag7f8i27ub1" path="res://player/model/faces/open.png" id="2_ymnw0"]
[resource] [resource]
render_priority = 0 render_priority = 0
@ -12,4 +12,4 @@ shader_parameter/screen_red_offset = Vector2(0, 0)
shader_parameter/screen_green_offset = Vector2(0, 0) shader_parameter/screen_green_offset = Vector2(0, 0)
shader_parameter/screen_blue_offset = Vector2(0, 0) shader_parameter/screen_blue_offset = Vector2(0, 0)
shader_parameter/pixel_size = 44.0 shader_parameter/pixel_size = 44.0
shader_parameter/face_texture = ExtResource("2_r4pvf") shader_parameter/face_texture = ExtResource("2_ymnw0")

View file

@ -4,4 +4,4 @@
albedo_color = Color(0, 0, 0, 1) albedo_color = Color(0, 0, 0, 1)
emission_enabled = true emission_enabled = true
emission = Color(0, 1, 0.392157, 1) emission = Color(0, 1, 0.392157, 1)
emission_energy_multiplier = 0.831129 emission_energy_multiplier = 2.82816

View file

@ -83,7 +83,6 @@ visible = false
mesh = SubResource("BoxMesh_kin6n") mesh = SubResource("BoxMesh_kin6n")
[node name="CameraController" type="Node3D" parent="."] [node name="CameraController" type="Node3D" parent="."]
top_level = true
script = ExtResource("2_2fob2") script = ExtResource("2_2fob2")
invert_mouse_y = true invert_mouse_y = true
tilt_upper_limit = 0.48 tilt_upper_limit = 0.48
@ -99,7 +98,6 @@ transform = Transform3D(1, 0, -7.10543e-15, 0, 1, 0, 0, 0, 1, 1.42109e-14, 2.384
[node name="PlayerCamera" type="Camera3D" parent="CameraController"] [node name="PlayerCamera" type="Camera3D" parent="CameraController"]
transform = Transform3D(-1, -3.71248e-14, -8.74228e-08, -3.23484e-08, 0.929023, 0.370022, 8.12178e-08, 0.370022, -0.929023, -8.74228e-07, 6.04006, -9.29023) transform = Transform3D(-1, -3.71248e-14, -8.74228e-08, -3.23484e-08, 0.929023, 0.370022, 8.12178e-08, 0.370022, -0.929023, -8.74228e-07, 6.04006, -9.29023)
top_level = true
attributes = SubResource("CameraAttributesPractical_2ooex") attributes = SubResource("CameraAttributesPractical_2ooex")
fov = 50.0 fov = 50.0
script = ExtResource("3_qxleh") script = ExtResource("3_qxleh")

View file

@ -21,6 +21,7 @@ config/icon="res://icon.png"
buses/default_bus_layout="res://defaults/audio_bus_layout.tres" buses/default_bus_layout="res://defaults/audio_bus_layout.tres"
driver/enable_input=true driver/enable_input=true
driver/mix_rate=48000
[display] [display]

View file

@ -20,4 +20,6 @@ var id: int
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
if not is_multiplayer_authority(): return if not is_multiplayer_authority(): return
speaking = Microphone.is_speaking
if speaking != Microphone.is_speaking:
speaking = Microphone.is_speaking

View file

@ -8,18 +8,23 @@ var speak_action: StringName = "speak"
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
if not Input.is_action_pressed(speak_action) or EditMode.is_enabled: if not Input.is_action_pressed(speak_action) or EditMode.is_enabled:
is_speaking = false set_speaking(false)
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
if EditMode.is_enabled: return if EditMode.is_enabled: return
if event.is_action_pressed(speak_action): if event.is_action_pressed(speak_action):
is_speaking = true set_speaking(true)
if event.is_action_released(speak_action): if event.is_action_released(speak_action):
is_speaking = false set_speaking(false)
func set_speaking(speaking: bool) -> void:
if speaking == is_speaking: return
is_speaking = speaking
func _exit_tree() -> void: func _exit_tree() -> void:
is_speaking = false set_speaking(false)

View file

@ -3,7 +3,7 @@ extends Node
@export var user_scn: PackedScene @export var user_scn: PackedScene
@export var player_spawner: PlayerSpawner @export var player_spawner: PlayerSpawner
var mic_capture: VOIPInputCapture var opuschunked: AudioEffectOpusChunked
var users = {} # {Peer ID: VoipUser} var users = {} # {Peer ID: VoipUser}
@ -15,8 +15,7 @@ func _ready() -> void:
player_spawner.player_spawned.connect(player_spawned) player_spawner.player_spawned.connect(player_spawned)
var mic_bus = AudioServer.get_bus_index("Record") var mic_bus = AudioServer.get_bus_index("Record")
mic_capture = AudioServer.get_bus_effect(mic_bus, 0) opuschunked = AudioServer.get_bus_effect(mic_bus, 0)
mic_capture.packet_ready.connect(voice_packet_ready)
func peer_connected(id: int) -> void: func peer_connected(id: int) -> void:
@ -44,22 +43,22 @@ func player_spawned(id: int, player: Player) -> void:
if users.has(id): users[id].set_anchor(player) if users.has(id): users[id].set_anchor(player)
func voice_packet_ready(packet: PackedByteArray) -> void:
if not Microphone.is_speaking: return
if Connection.is_peer_connected:
rpc("voice_packet_received", packet)
@rpc("any_peer", "call_remote", "unreliable_ordered", 1)
func voice_packet_received(packet: PackedByteArray) -> void:
if multiplayer.is_server(): return
var sender_id = multiplayer.get_remote_sender_id()
users[sender_id].stream.push_packet(packet)
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
if not Connection.is_peer_connected: return if not Connection.is_peer_connected: return
if multiplayer.is_server(): return if multiplayer.is_server(): return
mic_capture.send_test_packets() var prepend = PackedByteArray()
while opuschunked.chunk_available():
var opusdata: PackedByteArray = opuschunked.read_opus_packet(prepend)
opuschunked.drop_chunk()
if not Microphone.is_speaking: continue
rpc("opus_data_received", opusdata)
@rpc("any_peer", "call_remote", "unreliable_ordered", 1)
func opus_data_received(opusdata: PackedByteArray) -> void:
if multiplayer.is_server(): return
var sender_id = multiplayer.get_remote_sender_id()
users[sender_id].opuspacketsbuffer.append(opusdata)

View file

@ -8,9 +8,18 @@ class_name VoipUser
var user_id: int var user_id: int
var anchor: Node3D var anchor: Node3D
var audiostreamopuschunked : AudioStreamOpusChunked
var opuspacketsbuffer: Array[PackedByteArray] = []
func _ready() -> void: func _ready() -> void:
user_data_events.user_volume_changed.connect(change_volume) user_data_events.user_volume_changed.connect(change_volume)
audiostreamopuschunked = stream as AudioStreamOpusChunked
func _process(_delta: float) -> void:
while audiostreamopuschunked.chunk_space_available() and not opuspacketsbuffer.is_empty():
audiostreamopuschunked.push_opus_packet(opuspacketsbuffer.pop_front(), 0, 0)
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:

View file

@ -3,8 +3,7 @@
[ext_resource type="Script" path="res://voip/voip_user.gd" id="1_wo4b3"] [ext_resource type="Script" path="res://voip/voip_user.gd" id="1_wo4b3"]
[ext_resource type="Resource" uid="uid://rclnl7v8k722" path="res://user_data/user_data_events.res" id="2_mt25f"] [ext_resource type="Resource" uid="uid://rclnl7v8k722" path="res://user_data/user_data_events.res" id="2_mt25f"]
[sub_resource type="AudioStreamVOIP" id="AudioStreamVOIP_mku04"] [sub_resource type="AudioStreamOpusChunked" id="AudioStreamOpusChunked_ess21"]
resource_local_to_scene = true
[sub_resource type="Curve" id="Curve_q0foc"] [sub_resource type="Curve" id="Curve_q0foc"]
bake_resolution = 1000 bake_resolution = 1000
@ -12,7 +11,7 @@ _data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.142241, 0.010989), 0.0, 0.0, 0
point_count = 5 point_count = 5
[node name="VoipUser" type="AudioStreamPlayer3D"] [node name="VoipUser" type="AudioStreamPlayer3D"]
stream = SubResource("AudioStreamVOIP_mku04") stream = SubResource("AudioStreamOpusChunked_ess21")
attenuation_model = 1 attenuation_model = 1
volume_db = -12.0 volume_db = -12.0
unit_size = 15.0 unit_size = 15.0