Skip to content

Commit 91a2786

Browse files
committed
Add IAudioHandler (#2727)
* Feature Request - Add IAudioHandler - For performance reasons we return NULL if no audiohandler is assigned - No example is provided currently Initial implementation for #2714
1 parent 1d4e2a8 commit 91a2786

File tree

12 files changed

+359
-7
lines changed

12 files changed

+359
-7
lines changed

CefSharp.Core/Internals/ClientAdapter.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,42 @@ namespace CefSharp
11561156
}
11571157
}
11581158

1159+
void ClientAdapter::OnAudioStreamStarted(CefRefPtr<CefBrowser> browser, int audio_stream_id, int channels, ChannelLayout channel_layout, int sample_rate, int frames_per_buffer)
1160+
{
1161+
auto handler = _browserControl->AudioHandler;
1162+
1163+
if (handler != nullptr)
1164+
{
1165+
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());
1166+
1167+
handler->OnAudioStreamStarted(_browserControl, browserWrapper, audio_stream_id, channels, (CefSharp::Enums::ChannelLayout)channel_layout, sample_rate, frames_per_buffer);
1168+
}
1169+
}
1170+
1171+
void ClientAdapter::OnAudioStreamPacket(CefRefPtr<CefBrowser> browser, int audio_stream_id, const float** data, int frames, int64 pts)
1172+
{
1173+
auto handler = _browserControl->AudioHandler;
1174+
1175+
if (handler != nullptr)
1176+
{
1177+
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());
1178+
1179+
handler->OnAudioStreamPacket(_browserControl, browserWrapper, audio_stream_id, IntPtr((void *)data), frames, pts);
1180+
}
1181+
}
1182+
1183+
void ClientAdapter::OnAudioStreamStopped(CefRefPtr<CefBrowser> browser, int audio_stream_id)
1184+
{
1185+
auto handler = _browserControl->AudioHandler;
1186+
1187+
if (handler != nullptr)
1188+
{
1189+
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());
1190+
1191+
handler->OnAudioStreamStopped(_browserControl, browserWrapper, audio_stream_id);
1192+
}
1193+
}
1194+
11591195
bool ClientAdapter::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message)
11601196
{
11611197
auto handled = false;

CefSharp.Core/Internals/ClientAdapter.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ namespace CefSharp
3232
public CefDialogHandler,
3333
public CefDragHandler,
3434
public CefDownloadHandler,
35-
public CefFindHandler
35+
public CefFindHandler,
36+
public CefAudioHandler
3637
{
3738
private:
3839
gcroot<IWebBrowserInternal^> _browserControl;
@@ -100,6 +101,17 @@ namespace CefSharp
100101
virtual DECL CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE { return this; }
101102
virtual DECL CefRefPtr<CefDragHandler> GetDragHandler() OVERRIDE { return this; }
102103
virtual DECL CefRefPtr<CefFindHandler> GetFindHandler() OVERRIDE { return this; }
104+
virtual DECL CefRefPtr<CefAudioHandler> GetAudioHandler() OVERRIDE
105+
{
106+
//Audio Mirroring in CEF is only enabled when we a handler is returned
107+
//We return NULL if no handler is specified for performance reasons
108+
if (_browserControl->AudioHandler == nullptr)
109+
{
110+
return NULL;
111+
}
112+
113+
return this;
114+
}
103115
virtual DECL bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) OVERRIDE;
104116

105117

@@ -195,7 +207,12 @@ namespace CefSharp
195207
CefRefPtr<CefDownloadItemCallback> callback) OVERRIDE;
196208

197209
//CefFindHandler
198-
virtual DECL void OnFindResult(CefRefPtr<CefBrowser> browser, int identifier, int count, const CefRect& selectionRect, int activeMatchOrdinal, bool finalUpdate);
210+
virtual DECL void OnFindResult(CefRefPtr<CefBrowser> browser, int identifier, int count, const CefRect& selectionRect, int activeMatchOrdinal, bool finalUpdate) OVERRIDE;
211+
212+
//CefAudioHandler
213+
virtual DECL void OnAudioStreamStarted(CefRefPtr<CefBrowser> browser, int audio_stream_id, int channels, ChannelLayout channel_layout, int sample_rate, int frames_per_buffer) OVERRIDE;
214+
virtual DECL void OnAudioStreamPacket(CefRefPtr<CefBrowser> browser, int audio_stream_id, const float** data, int frames, int64 pts) OVERRIDE;
215+
virtual DECL void OnAudioStreamStopped(CefRefPtr<CefBrowser> browser, int audio_stream_id) OVERRIDE;
199216

200217
//sends out an eval script request to the render process
201218
Task<JavascriptResponse^>^ EvaluateScriptAsync(int browserId, bool isBrowserPopup, int64 frameId, String^ script, String^ scriptUrl, int startLine, Nullable<TimeSpan> timeout);

CefSharp.Example/CefSharp.Example.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
</ItemGroup>
7272
<ItemGroup>
7373
<Compile Include="Callback\RunFileDialogCallback.cs" />
74+
<Compile Include="Handlers\AudioHandler.cs" />
7475
<Compile Include="Handlers\ExtensionHandler.cs" />
7576
<Compile Include="JavascriptBinding\AsyncBoundObject.cs" />
7677
<Compile Include="JavascriptBinding\BoundObject.cs" />
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright © 2019 The CefSharp Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4+
5+
using System;
6+
using CefSharp.Enums;
7+
8+
namespace CefSharp.Example.Handlers
9+
{
10+
public class AudioHandler : IAudioHandler
11+
{
12+
private ChannelLayout channelLayout;
13+
private int channelCount;
14+
private int sampleRate;
15+
16+
void IAudioHandler.OnAudioStreamPacket(IWebBrowser chromiumWebBrowser, IBrowser browser, int audioStreamId, IntPtr data, int noOfFrames, long pts)
17+
{
18+
//NOTE: data is an array representing the raw PCM data as a floating point type, i.e. 4-byte value(s)
19+
//Based on and the channelLayout value passed to IAudioHandler.OnAudioStreamStarted
20+
//you can calculate the size of the data array in bytes.
21+
}
22+
23+
void IAudioHandler.OnAudioStreamStarted(IWebBrowser chromiumWebBrowser, IBrowser browser, int audioStreamId, int channels, ChannelLayout channelLayout, int sampleRate, int framesPerBuffer)
24+
{
25+
this.channelLayout = channelLayout;
26+
this.channelCount = channels;
27+
this.sampleRate = sampleRate;
28+
}
29+
30+
void IAudioHandler.OnAudioStreamStopped(IWebBrowser chromiumWebBrowser, IBrowser browser, int audioStreamId)
31+
{
32+
33+
}
34+
}
35+
}

CefSharp.OffScreen/ChromiumWebBrowser.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,15 @@ public bool IsDisposed
183183
/// </summary>
184184
/// <value>The find handler.</value>
185185
public IFindHandler FindHandler { get; set; }
186-
186+
/// <summary>
187+
/// Implement <see cref="IAudioHandler" /> to handle audio events.
188+
/// </summary>
189+
public IAudioHandler AudioHandler { get; set; }
187190
/// <summary>
188191
/// Implement <see cref="IAccessibilityHandler" /> to handle events related to accessibility.
189192
/// </summary>
190193
/// <value>The accessibility handler.</value>
191194
public IAccessibilityHandler AccessibilityHandler { get; set; }
192-
193195
/// <summary>
194196
/// Event handler that will get called when the resource load for a navigation fails or is canceled.
195197
/// It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI

CefSharp.WinForms/ChromiumWebBrowser.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ public IRequestContext RequestContext
221221
/// <value>The find handler.</value>
222222
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(null)]
223223
public IFindHandler FindHandler { get; set; }
224-
224+
/// <summary>
225+
/// Implement <see cref="IAudioHandler" /> to handle audio events.
226+
/// </summary>
227+
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(null)]
228+
public IAudioHandler AudioHandler { get; set; }
225229
/// <summary>
226230
/// The <see cref="IFocusHandler" /> for this ChromiumWebBrowser.
227231
/// </summary>

CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public BrowserTabView()
9696
downloadHandler.OnBeforeDownloadFired += OnBeforeDownloadFired;
9797
downloadHandler.OnDownloadUpdatedFired += OnDownloadUpdatedFired;
9898
browser.DownloadHandler = downloadHandler;
99+
browser.AudioHandler = new AudioHandler();
99100

100101
//Read an embedded bitmap into a memory stream then register it as a resource you can then load custom://cefsharp/images/beach.jpg
101102
var beachImageStream = new MemoryStream();
@@ -147,7 +148,7 @@ public BrowserTabView()
147148
var errorBody = string.Format("<html><body bgcolor=\"white\"><h2>Failed to load URL {0} with error {1} ({2}).</h2></body></html>",
148149
args.FailedUrl, args.ErrorText, args.ErrorCode);
149150

150-
args.Frame.LoadHtml(errorBody, base64Encode:true);
151+
args.Frame.LoadHtml(errorBody, base64Encode: true);
151152
};
152153

153154
CefExample.RegisterTestResources(browser);

CefSharp.Wpf/ChromiumWebBrowser.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,10 @@ public IRequestContext RequestContext
268268
/// </summary>
269269
/// <value>The find handler.</value>
270270
public IFindHandler FindHandler { get; set; }
271-
271+
/// <summary>
272+
/// Implement <see cref="IAudioHandler" /> to handle audio events.
273+
/// </summary>
274+
public IAudioHandler AudioHandler { get; set; }
272275
/// <summary>
273276
/// Implement <see cref="IAccessibilityHandler" /> to handle events related to accessibility.
274277
/// </summary>

CefSharp/CefSharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
<Compile Include="CdmRegistration.cs" />
100100
<Compile Include="DefaultApp.cs" />
101101
<Compile Include="Enums\AlphaType.cs" />
102+
<Compile Include="Enums\ChannelLayout.cs" />
102103
<Compile Include="Enums\PointerType.cs" />
103104
<Compile Include="Enums\TextInputMode.cs" />
104105
<Compile Include="Enums\TouchEventType.cs" />
@@ -113,6 +114,7 @@
113114
<Compile Include="Handler\IAccessibilityHandler.cs" />
114115
<Compile Include="Handler\IExtensionHandler.cs" />
115116
<Compile Include="IApp.cs" />
117+
<Compile Include="Handler\IAudioHandler.cs" />
116118
<Compile Include="IExtension.cs" />
117119
<Compile Include="ISchemeRegistrar.cs" />
118120
<Compile Include="IValue.cs" />

CefSharp/Enums/ChannelLayout.cs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// Copyright © 2019 The CefSharp Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4+
5+
namespace CefSharp.Enums
6+
{
7+
/// <summary>
8+
/// Enumerates the various representations of the ordering of audio channels.
9+
/// Logged to UMA, so never reuse a value, always add new/greater ones!
10+
/// See media\base\channel_layout.h
11+
/// </summary>
12+
public enum ChannelLayout
13+
{
14+
/// <summary>
15+
/// None
16+
/// </summary>
17+
LayoutNone = 0,
18+
19+
/// <summary>
20+
/// Unsupported
21+
/// </summary>
22+
LayoutUnsupported = 1,
23+
24+
/// <summary>
25+
/// Front C
26+
/// </summary>
27+
LayoutMono = 2,
28+
29+
/// <summary>
30+
/// Front L, Front R
31+
/// </summary>
32+
LayoutStereo = 3,
33+
34+
/// <summary>
35+
/// Front L, Front R, Back C
36+
/// </summary>
37+
Layout2_1 = 4,
38+
39+
/// <summary>
40+
/// Front L, Front R, Front C
41+
/// </summary>
42+
LayoutSurround = 5,
43+
44+
/// <summary>
45+
/// Front L, Front R, Front C, Back C
46+
/// </summary>
47+
Layout4_0 = 6,
48+
49+
/// <summary>
50+
/// Front L, Front R, Side L, Side R
51+
/// </summary>
52+
Layout2_2 = 7,
53+
54+
/// <summary>
55+
/// Front L, Front R, Back L, Back R
56+
/// </summary>
57+
LayoutQuad = 8,
58+
59+
/// <summary>
60+
/// Front L, Front R, Front C, Side L, Side R
61+
/// </summary>
62+
Layout5_0 = 9,
63+
64+
/// <summary>
65+
/// Front L, Front R, Front C, LFE, Side L, Side R
66+
/// </summary>
67+
Layout5_1 = 10,
68+
69+
/// <summary>
70+
/// Front L, Front R, Front C, Back L, Back R
71+
/// </summary>
72+
Layout5_0Back = 11,
73+
74+
/// <summary>
75+
/// Front L, Front R, Front C, LFE, Back L, Back R
76+
/// </summary>
77+
Layout5_1Back = 12,
78+
79+
/// <summary>
80+
/// Front L, Front R, Front C, Side L, Side R, Back L, Back R
81+
/// </summary>
82+
Layout7_0 = 13,
83+
84+
/// <summary>
85+
/// Front L, Front R, Front C, LFE, Side L, Side R, Back L, Back R
86+
/// </summary>
87+
Layout7_1 = 14,
88+
89+
/// <summary>
90+
/// Front L, Front R, Front C, LFE, Side L, Side R, Front LofC, Front RofC
91+
/// </summary>
92+
Layout7_1Wide = 15,
93+
94+
/// <summary>
95+
/// Stereo L, Stereo R
96+
/// </summary>
97+
LayoutStereoDownMix = 16,
98+
99+
/// <summary>
100+
/// Stereo L, Stereo R, LFE
101+
/// </summary>
102+
Layout2Point1 = 17,
103+
104+
/// <summary>
105+
/// Stereo L, Stereo R, Front C, LFE
106+
/// </summary>
107+
Layout3_1 = 18,
108+
109+
/// <summary>
110+
/// Stereo L, Stereo R, Front C, Rear C, LFE
111+
/// </summary>
112+
Layout4_1 = 19,
113+
114+
/// <summary>
115+
/// Stereo L, Stereo R, Front C, Side L, Side R, Back C
116+
/// </summary>
117+
Layout6_0 = 20,
118+
119+
/// <summary>
120+
/// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC
121+
/// </summary>
122+
Layout6_0Front = 21,
123+
124+
/// <summary>
125+
/// Stereo L, Stereo R, Front C, Rear L, Rear R, Rear C
126+
/// </summary>
127+
LayoutHexagonal = 22,
128+
129+
/// <summary>
130+
/// Stereo L, Stereo R, Front C, LFE, Side L, Side R, Rear Center
131+
/// </summary>
132+
Layout6_1 = 23,
133+
134+
/// <summary>
135+
/// Stereo L, Stereo R, Front C, LFE, Back L, Back R, Rear Center
136+
/// </summary>
137+
Layout6_1Back = 24,
138+
139+
/// <summary>
140+
/// Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC, LFE
141+
/// </summary>
142+
Layout6_1Front = 25,
143+
144+
/// <summary>
145+
/// Front L, Front R, Front C, Side L, Side R, Front LofC, Front RofC
146+
/// </summary>
147+
Layout7_0Front = 26,
148+
149+
/// <summary>
150+
/// Front L, Front R, Front C, LFE, Back L, Back R, Front LofC, Front RofC
151+
/// </summary>
152+
Layout7_1WideBack = 27,
153+
154+
/// <summary>
155+
/// Front L, Front R, Front C, Side L, Side R, Rear L, Back R, Back C.
156+
/// </summary>
157+
LayoutOctagonal = 28,
158+
159+
/// <summary>
160+
/// Channels are not explicitly mapped to speakers.
161+
/// </summary>
162+
LayoutDiscrete = 29,
163+
164+
/// <summary>
165+
/// Front L, Front R, Front C. Front C contains the keyboard mic audio. This
166+
/// layout is only intended for input for WebRTC. The Front C channel
167+
/// is stripped away in the WebRTC audio input pipeline and never seen outside
168+
/// of that.
169+
/// </summary>
170+
LayoutStereoKeyboardAndMic = 30,
171+
172+
/// <summary>
173+
/// Front L, Front R, Side L, Side R, LFE
174+
/// </summary>
175+
Layout4_1QuadSize = 31,
176+
177+
/// <summary>
178+
/// Actual channel layout is specified in the bitstream and the actual channel
179+
/// count is unknown at Chromium media pipeline level (useful for audio
180+
/// pass-through mode).
181+
/// </summary>
182+
LayoutBitstream = 32,
183+
184+
// Max value, must always equal the largest entry ever logged.
185+
LayoutMax = LayoutBitstream
186+
}
187+
}

0 commit comments

Comments
 (0)