Skip to content

Commit

Permalink
Add routing CEF audio to Godot #42 #31
Browse files Browse the repository at this point in the history
Update 2d with AudioStreamPlayer2D and 3d demos with AudioStreamPlayer3D
  • Loading branch information
Lecrapouille committed Jan 29, 2024
1 parent 45d8086 commit eb47877
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 15 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Contributors:
Raphipod (docs, fixes, Windows)
Daniel Sanche (javascript injection, fixes)
BlayTheNinth (portage to Godot 4.2)
pixaline (Routing audio)
40 changes: 36 additions & 4 deletions addons/gdcef/demos/2D/CEF.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ extends Control

# Default pages
const DEFAULT_PAGE = "user://default_page.html"
const RADIO_PAGE = "https://www.programmes-radio.com/fr/stream-e8BxeoRhsz9jY9mXXRiFTE/ecouter-KPJK"
const RADIO_PAGE = "http://streaming.radio.co/s9378c22ee/listen"
# "https://www.programmes-radio.com/fr/stream-e8BxeoRhsz9jY9mXXRiFTE/ecouter-KPJK"
const HOME_PAGE = "https://github.com/Lecrapouille/gdcef"

# The current browser as Godot node
Expand All @@ -17,6 +18,8 @@ const HOME_PAGE = "https://github.com/Lecrapouille/gdcef"
# Memorize if the mouse was pressed
@onready var mouse_pressed : bool = false

@onready var playback = null

# ==============================================================================
# Callback when a page has ended to load with success (200): we print a message
# ==============================================================================
Expand All @@ -33,6 +36,9 @@ func _on_page_loaded(node):
# Display a load error message using a data: URI.
# ==============================================================================
func _on_page_failed_loading(aborted, msg_err, node):
# FIXME: I dunno why the radio page is considered as canceled by the user
if node.get_url() == RADIO_PAGE:
return
var html = "<html><body bgcolor=\"white\"><h2>Failed to load URL " + node.get_url()
if aborted:
html = html + " aborted by the user!</h2></body></html>"
Expand Down Expand Up @@ -183,9 +189,11 @@ func _on_radio_pressed():
# ==============================================================================
# Mute/unmute the sound
# ==============================================================================
func _on_Mute_pressed():
if current_browser != null:
current_browser.set_muted(not current_browser.is_muted())
func _on_mute_pressed():
if current_browser == null:
return
current_browser.set_muted($Panel/VBox/HBox2/Mute.button_pressed)
$AudioStreamPlayer2D.stream_paused = $Panel/VBox/HBox2/Mute.button_pressed
pass

####
Expand Down Expand Up @@ -285,6 +293,7 @@ func _ready():
push_error($CEF.get_error())
return
print("CEF version: " + $CEF.get_full_version())
print("You are listening CEF native audio")

# Wait one frame for the texture rect to get its size
current_browser = await create_browser(HOME_PAGE)
Expand All @@ -295,3 +304,26 @@ func _ready():
# ==============================================================================
func _process(_delta):
pass

# ==============================================================================
# CEF audio will be routed to this Godot stream object.
# ==============================================================================
func _on_routing_audio_pressed():
if current_browser == null:
return
if $Panel/VBox/HBox2/RoutingAudio.button_pressed:
print("You are listening CEF audio routed to Godot and filtered with reverberation effect")
$AudioStreamPlayer2D.stream = AudioStreamGenerator.new()
$AudioStreamPlayer2D.stream.set_buffer_length(1)
$AudioStreamPlayer2D.playing = true
current_browser.audio_stream = $AudioStreamPlayer2D.get_stream_playback()
else:
print("You are listening CEF native audio")
current_browser.audio_stream = null
current_browser.set_muted(false)
$Panel/VBox/HBox2/Mute.button_pressed = false
# Not necessary, but, I do not know what, to apply the new mode, the user
# shall click on the html halt button and click on the html button. To avoid
# this, we reload the page.
current_browser.reload()
pass
13 changes: 10 additions & 3 deletions addons/gdcef/demos/2D/CEF.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ layout_mode = 2
tooltip_text = "Load a page with sound"
text = "Radio"

[node name="Mute" type="Button" parent="Panel/VBox/HBox2"]
[node name="RoutingAudio" type="CheckBox" parent="Panel/VBox/HBox2"]
layout_mode = 2
tooltip_text = "Route CEF audio to Godot"
text = " Audio routing"

[node name="Mute" type="CheckBox" parent="Panel/VBox/HBox2"]
layout_mode = 2
tooltip_text = "Mute/unmute the sound"
text = "Mute sound"

[node name="Info2" type="Label" parent="Panel/VBox/HBox2"]
Expand All @@ -127,6 +131,8 @@ anchor_bottom = 1.0
edit_alpha = false
presets_visible = false

[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]

[connection signal="pressed" from="Panel/VBox/HBox/New" to="." method="_on_Add_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox/Home" to="." method="_on_Home_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox/Go" to="." method="_on_go_pressed"]
Expand All @@ -139,5 +145,6 @@ presets_visible = false
[connection signal="resized" from="Panel/VBox/TextureRect" to="." method="_on_texture_rect_resized"]
[connection signal="pressed" from="Panel/VBox/HBox2/BGColor" to="." method="_on_BGColor_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox2/Radio" to="." method="_on_radio_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox2/Mute" to="." method="_on_Mute_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox2/RoutingAudio" to="." method="_on_routing_audio_pressed"]
[connection signal="pressed" from="Panel/VBox/HBox2/Mute" to="." method="_on_mute_pressed"]
[connection signal="color_changed" from="ColorPopup/ColorPicker" to="." method="_on_ColorPicker_color_changed"]
8 changes: 8 additions & 0 deletions addons/gdcef/demos/2D/default_bus_layout.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://bebfjoqlbtwr1"]

[sub_resource type="AudioEffectReverb" id="AudioEffectReverb_ox0vc"]
resource_name = "Reverb"

[resource]
bus/0/effect/0/effect = SubResource("AudioEffectReverb_ox0vc")
bus/0/effect/0/enabled = true
2 changes: 1 addition & 1 deletion addons/gdcef/demos/3D/CEF.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ offset_bottom = 26.0
[connection signal="gui_input" from="Panel/TextureRect" to="." method="_on_TextureRect_gui_input"]
[connection signal="pressed" from="Panel/Home" to="." method="_on_Home_pressed"]
[connection signal="pressed" from="Panel/Prev" to="." method="_on_Prev_pressed"]
[connection signal="pressed" from="Panel/Next" to="." method="_on_Prev_pressed"]
[connection signal="pressed" from="Panel/Next" to="." method="_on_Next_pressed"]
[connection signal="pressed" from="Panel/Next" to="." method="_on_Prev_pressed"]
[connection signal="text_changed" from="Panel/TextEdit" to="." method="_on_TextEdit_text_changed"]
20 changes: 17 additions & 3 deletions addons/gdcef/demos/3D/GUI.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
extends Control

# Name of the browser
const browser_name = "browser1"
const browser_name = "browser"

# Page with sound
# "https://www.programmes-radio.com/fr/stream-e8BxeoRhsz9jY9mXXRiFTE/ecouter-KPJK"
const RADIO_URL = "http://streaming.radio.co/s9378c22ee/listen"
const HOME_URL = "https://github.com/Lecrapouille/gdcef"

# Memorize if the mouse was pressed
@onready var mouse_pressed : bool = false
Expand All @@ -20,7 +25,7 @@ func _on_Home_pressed():
if browser == null:
$Panel/Label.set_text("Failed getting Godot node " + browser_name)
return
browser.load_url("https://bitbucket.org/chromiumembedded/cef/wiki/Home")
browser.load_url(HOME_URL)
pass

# ==============================================================================
Expand Down Expand Up @@ -161,10 +166,19 @@ func _ready():
# {"image_loading", true}
# {"databases", true}
# {"webgl", true}
var browser = $CEF.create_browser("https://github.com/Lecrapouille/gdcef", $Panel/TextureRect, {"javascript":true})
var browser = $CEF.create_browser(RADIO_URL, $Panel/TextureRect, {"javascript":true})
browser.name = browser_name
browser.connect("on_page_loaded", _on_page_loaded)
browser.connect("on_page_failed_loading", _on_page_failed_loading)
browser.set_zoom_level(0.05)

# 3D sound
get_tree().get_root().print_tree_pretty()
var player = get_node("/root/GUIin3D/Background/Cube2/AudioStreamPlayer3D")
player.stream = AudioStreamGenerator.new()
player.stream.set_buffer_length(1)
player.playing = true
browser.audio_stream = player.get_stream_playback()
pass

# ==============================================================================
Expand Down
13 changes: 12 additions & 1 deletion addons/gdcef/demos/3D/gui_in_3d.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ environment = SubResource("Environment_niyks")
[node name="GUIPanel3D" parent="." instance=ExtResource("1")]

[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 0.999999, 0, 0, 3)
transform = Transform3D(0.997487, 0, 0.0708434, 0, 1, 0, -0.0708434, 0, 0.997487, 0.372951, 0, 1.79731)
fov = 74.0
near = 0.1

Expand Down Expand Up @@ -99,3 +99,14 @@ surface_material_override/0 = SubResource("4")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.88761, 2.01326, 0.374871)
mesh = SubResource("3")
surface_material_override/0 = SubResource("4")

[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Background/Cube2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.09059, 0, 8.36119)
volume_db = 20.0
emission_angle_enabled = true
emission_angle_degrees = 17.0

[node name="Cube3" type="MeshInstance3D" parent="Background"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.62461, 1.46641, -0.69153)
mesh = SubResource("3")
surface_material_override/0 = SubResource("4")
36 changes: 35 additions & 1 deletion addons/gdcef/gdcef/src/gdbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ void GDBrowserView::_bind_methods()
ClassDB::bind_method(D_METHOD("set_mouse_wheel_horizontal"), &GDBrowserView::mouseWheelHorizontal);
ClassDB::bind_method(D_METHOD("set_muted"), &GDBrowserView::mute);
ClassDB::bind_method(D_METHOD("is_muted"), &GDBrowserView::muted);
ClassDB::bind_method(D_METHOD("set_audio_stream", "audio"), &GDBrowserView::setAudioStreamer);
ClassDB::bind_method(D_METHOD("get_audio_stream"), &GDBrowserView::getAudioStreamer);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_NODE_TYPE,
"AudioStreamGeneratorPlayback"), "set_audio_stream", "get_audio_stream");

ADD_SIGNAL(MethodInfo("on_page_loaded", PropertyInfo(Variant::OBJECT, "node")));
ADD_SIGNAL(MethodInfo("on_page_failed_loading", PropertyInfo(Variant::BOOL, "aborted"),
Expand Down Expand Up @@ -138,6 +142,7 @@ GDBrowserView::GDBrowserView()
BROWSER_DEBUG_VAL("Create Godot texture");

m_impl = new GDBrowserView::Impl(*this);
assert((m_impl != nullptr) && "Failed allocating GDBrowserView");
m_image.instantiate();
m_texture.instantiate();
}
Expand Down Expand Up @@ -303,7 +308,6 @@ void GDBrowserView::stopLoading()
//------------------------------------------------------------------------------
void GDBrowserView::executeJavaScript(godot::String javascript)
{

if (m_browser && m_browser->GetMainFrame())
{
CefString codeStr;
Expand Down Expand Up @@ -462,3 +466,33 @@ bool GDBrowserView::muted()

return m_browser->GetHost()->IsAudioMuted();
}

//------------------------------------------------------------------------------
void GDBrowserView::onAudioStreamStarted(CefRefPtr<CefBrowser> browser,
const CefAudioParameters& params,
int channels)
{
m_impl->m_audio.channels = int(params.channel_layout);
}

//------------------------------------------------------------------------------
void GDBrowserView::onAudioStreamPacket(CefRefPtr<CefBrowser> browser,
const float** data, int frames, int64_t pts)
{
if ((m_impl == nullptr) || (m_impl->m_audio.streamer == nullptr))
{
return ;
}

if ((data == nullptr) || (frames <= 0) || (m_impl->m_audio.channels == -1))
return;

auto& streamer = *(m_impl->m_audio.streamer.ptr());
if (streamer.can_push_buffer(frames))
{
for (int i = 0; i < frames; i++)
{
streamer.push_frame(godot::Vector2(data[0][i], data[0][i]));
}
}
}
Loading

0 comments on commit eb47877

Please sign in to comment.