|
| 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