Skip to content

Commit 3011d18

Browse files
Diana QuDiana Qujasonstephen15david-risney
authored
[Media API]: Requesting API Review (#1658)
* api draft * fill in details for mute unmute * add background * added background section * naming typo Co-authored-by: David Risney <dave@deletethis.net> * IsCurrentlyAudible comment change Co-authored-by: David Risney <dave@deletethis.net> * update c# section * add audible, mute, unmute sample code. mute part might change * update c++ sample code * remove accidential change to other api * update .net sample code * update sample code. rename audible. update comment * remove event handler is muted * Use value for API Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * add mising ismuted api * change snippet location * put mute related snippet together * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * add check failure. change handler iout * use ICoreWebView2 as input for event handler * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * Update specs/Media.md Co-authored-by: David Risney <dave@deletethis.net> * removing staging perfix * ICoreWebView2_6 : ICoreWebView2_5 * modify sample app to use ICoreWebView2_6 * rename get_IsAudioPlaying related API * change mute to settable and change sample code * add mute state changed event * update .net code Co-authored-by: Diana Qu <xiaqu@microsoft.com> Co-authored-by: Jason Stephen <22718545+jasonstephen15@users.noreply.github.com> Co-authored-by: David Risney <dave@deletethis.net>
1 parent 64096a5 commit 3011d18

1 file changed

Lines changed: 220 additions & 0 deletions

File tree

specs/Media.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Background
2+
WebView2 is a control that developers can implement for part of, or for the entirety of their app. In the either case, developers may need the ability to control the media within the webview's bounds. This API will allow developers to control the sound of each webview2 instance by enabling the mute/unmute of the media within the webview. There will also be the ability to check if the sound is muted or audible.
3+
4+
# Description
5+
Enable end developer to `Mute`, `Unmute` a webview content. And ability to check for the `IsMuted` and `IsAudioPlaying`.
6+
7+
# Examples
8+
9+
The following code snippet demonstrates how the Media related API can be used:
10+
11+
## Win32 C++
12+
13+
```cpp
14+
//! [IsDocumentPlayingAudioChanged] [IsDocumentPlayingAudio] [ToggleIsMuted]
15+
AudioComponent::AudioComponent(AppWindow* appWindow)
16+
: m_appWindow(appWindow), m_webView(appWindow->GetWebView())
17+
{
18+
webview6 = m_webView.try_query<ICoreWebView2_6>();
19+
// Register a handler for the IsDocumentPlayingAudioChanged event.
20+
CHECK_FAILURE(webview6->add_IsDocumentPlayingAudioChanged(
21+
Callback<ICoreWebView2StagingIsDocumentPlayingAudioChangedEventHandler>(
22+
[this, webview6](ICoreWebView2* sender, IUnknown* args) -> HRESULT {
23+
UpdateTitleWithMuteState(webview6);
24+
return S_OK;
25+
})
26+
.Get(),
27+
&m_isDocumentPlayingAudioChangedToken));
28+
29+
// Register a handler for the IsMutedChanged event.
30+
CHECK_FAILURE(webview6->add_IsMutedChanged(
31+
Callback<ICoreWebView2StagingIsMutedChangedEventHandler>(
32+
[this, webview6](ICoreWebView2* sender, IUnknown* args) -> HRESULT {
33+
UpdateTitleWithMuteState(webview6);
34+
return S_OK;
35+
})
36+
.Get(),
37+
&m_isMutedChangedToken));
38+
}
39+
40+
// Toggle the mute state of the current window and show a mute or unmute icon on the title bar
41+
void AudioComponent::ToggleMuteState()
42+
{
43+
#ifdef USE_WEBVIEW2_STAGING
44+
auto webview6 = m_webView.try_query<ICoreWebView2Staging2>();
45+
if (webview6)
46+
{
47+
BOOL isMuted;
48+
webview6->get_IsMuted(&isMuted);
49+
CHECK_FAILURE(webview6->put_IsMuted(!isMuted));
50+
}
51+
#endif
52+
}
53+
54+
void AudioComponent::UpdateTitleWithMuteState(
55+
wil::com_ptr<ICoreWebView2Staging2> webview6)
56+
{
57+
BOOL isDocumentPlayingAudio;
58+
CHECK_FAILURE(webview6->get_IsDocumentPlayingAudio(&isDocumentPlayingAudio));
59+
60+
BOOL isMuted;
61+
CHECK_FAILURE(webview6->get_IsMuted(&isMuted));
62+
63+
wil::unique_cotaskmem_string title;
64+
CHECK_FAILURE(m_webView->get_DocumentTitle(&title));
65+
std::wstring result = L"";
66+
67+
if (isDocumentPlayingAudio)
68+
{
69+
if (isMuted)
70+
{
71+
result = L"🔇 " + std::wstring(title.get());
72+
}
73+
else
74+
{
75+
result = L"🔊 " + std::wstring(title.get());
76+
}
77+
}
78+
else
79+
{
80+
result = std::wstring(title.get());
81+
}
82+
83+
m_appWindow->SetDocumentTitle(result.c_str());
84+
}
85+
//! [IsDocumentPlayingAudioChanged] [IsDocumentPlayingAudio] [ToggleIsMuted]
86+
```
87+
88+
## .NET and WinRT
89+
90+
```c#
91+
void UpdateTitleWithMuteState()
92+
{
93+
bool isDocumentPlayingAudio = webView.CoreWebView2.IsDocumentPlayingAudio;
94+
bool isMuted = webView.CoreWebView2.IsMuted;
95+
string currentDocumentTitle = webView.CoreWebView2.DocumentTitle;
96+
if (isDocumentPlayingAudio)
97+
{
98+
if (isMuted)
99+
{
100+
this.Title = "🔇 " + currentDocumentTitle;
101+
}
102+
else
103+
{
104+
this.Title = "🔊 " + currentDocumentTitle;
105+
}
106+
}
107+
else
108+
{
109+
this.Title = currentDocumentTitle;
110+
}
111+
}
112+
void WebView_IsMutedChanged(object sender, object e)
113+
{
114+
UpdateTitleWithMuteState();
115+
}
116+
void WebView_IsDocumentPlayingAudioChanged(object sender, object e)
117+
{
118+
UpdateTitleWithMuteState();
119+
}
120+
121+
void ToggleMuteStateCmdExecuted(object target, ExecutedRoutedEventArgs e)
122+
{
123+
webView.CoreWebView2.IsMuted = !webView.CoreWebView2.IsMuted;
124+
}
125+
```
126+
127+
# API Notes
128+
129+
See [API Details](#api-details) section below for API reference.
130+
131+
# API Details
132+
133+
## Win32 C++
134+
135+
```IDL
136+
interface ICoreWebView2StagingIsMutedChangedEventHandler;
137+
interface ICoreWebView2StagingIsDocumentPlayingAudioChangedEventHandler;
138+
139+
[uuid(71c906d9-4a4d-4dbe-aa1b-db64f4de594e), object, pointer_default(unique)]
140+
interface ICoreWebView2_6 : ICoreWebView2_5 {
141+
/// Adds an event handler for the `IsMutedChanged` event.
142+
/// `IsMutedChanged` is raised when the IsMuted property changes value.
143+
///
144+
/// \snippet AudioComponent-Staging.cpp IsMutedChanged
145+
HRESULT add_IsMutedChanged(
146+
[in] ICoreWebView2StagingIsMutedChangedEventHandler* eventHandler,
147+
[out] EventRegistrationToken* token);
148+
149+
/// Remove an event handler previously added with `add_IsMutedChanged`.
150+
HRESULT remove_IsMutedChanged(
151+
[in] EventRegistrationToken token);
152+
153+
/// Indicates whether all audio output from this CoreWebView2 is muted or not.
154+
///
155+
/// \snippet AudioComponent-Staging.cpp ToggleIsMuted
156+
[propget] HRESULT IsMuted([out, retval] BOOL* value);
157+
158+
/// Sets the `IsMuted` property.
159+
///
160+
/// \snippet AudioComponent-Staging.cpp ToggleIsMuted
161+
[propput] HRESULT IsMuted([in] BOOL value);
162+
163+
/// Adds an event handler for the `IsDocumentPlayingAudioChanged` event.
164+
/// `IsDocumentPlayingAudioChanged` is raised when the IsDocumentPlayingAudio property changes value.
165+
///
166+
/// \snippet AudioComponent.cpp IsDocumentPlayingAudioChanged
167+
HRESULT add_IsDocumentPlayingAudioChanged(
168+
[in] ICoreWebView2IsDocumentPlayingAudioChangedEventHandler* eventHandler,
169+
[out] EventRegistrationToken* token);
170+
171+
/// Remove an event handler previously added with `add_IsDocumentPlayingAudioChanged`.
172+
HRESULT remove_IsDocumentPlayingAudioChanged(
173+
[in] EventRegistrationToken token);
174+
175+
/// Indicates whether any audio output from this CoreWebView2 is playing.
176+
/// This property will be true if audio is playing even if IsMuted is true.
177+
/// if there are audio currently playing.
178+
///
179+
/// \snippet AudioComponent.cpp IsDocumentPlayingAudio
180+
[propget] HRESULT IsDocumentPlayingAudio([out, retval] BOOL* value);
181+
}
182+
183+
/// Implements the interface to receive `IsDocumentPlayingAudioChanged` events. Use the
184+
/// IsDocumentPlayingAudio method to get the audible state.
185+
[uuid(5DEF109A-2F4B-49FA-B7F6-11C39E513328), object, pointer_default(unique)]
186+
interface ICoreWebView2StagingIsDocumentPlayingAudioChangedEventHandler : IUnknown {
187+
/// Provides the event args for the corresponding event. No event args exist
188+
/// and the `args` parameter is set to `null`.
189+
HRESULT Invoke([in] ICoreWebView2* sender, [in] IUnknown* args);
190+
}
191+
192+
/// Implements the interface to receive `IsMutedChanged` events. Use the
193+
/// IsMuted method to get the mute state.
194+
[uuid(57D90347-CD0E-4952-A4A2-7483A2756F08), object, pointer_default(unique)]
195+
interface ICoreWebView2StagingIsMutedChangedEventHandler : IUnknown {
196+
/// Provides the event args for the corresponding event. No event args exist
197+
/// and the `args` parameter is set to `null`.
198+
HRESULT Invoke([in] ICoreWebView2* sender, [in] IUnknown* args);
199+
}
200+
```
201+
202+
## .NET and WinRT
203+
204+
```c#
205+
namespace Microsoft.Web.WebView2.Core
206+
{
207+
208+
runtimeclass CoreWebView2
209+
{
210+
// ...
211+
Boolean IsMuted { get; set; };
212+
Boolean IsDocumentPlayingAudio { get; };
213+
214+
event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> IsMutedChanged;
215+
event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> IsDocumentPlayingAudioChanged;
216+
217+
// ...
218+
}
219+
}
220+
```

0 commit comments

Comments
 (0)