<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mayur Tendulkar</title>
    <description>The latest articles on DEV Community by Mayur Tendulkar (@mayten).</description>
    <link>https://dev.to/mayten</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F878017%2F4b48ab1a-eaf4-48dc-83a7-812544b6e2c2.jpeg</url>
      <title>DEV Community: Mayur Tendulkar</title>
      <link>https://dev.to/mayten</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayten"/>
    <language>en</language>
    <item>
      <title>Building a Video Calling App Using WPF &amp; Dyte</title>
      <dc:creator>Mayur Tendulkar</dc:creator>
      <pubDate>Mon, 13 Mar 2023 13:24:49 +0000</pubDate>
      <link>https://dev.to/dyte/building-a-video-calling-app-using-wpf-dyte-2g1m</link>
      <guid>https://dev.to/dyte/building-a-video-calling-app-using-wpf-dyte-2g1m</guid>
      <description>&lt;p&gt;&lt;a href="https://visualstudio.microsoft.com/vs/features/wpf/"&gt;Windows Presentation Foundation&lt;/a&gt;, also popularly known as WPF, is a popular UI framework for building Windows applications. Since its launch in 2006, it has gained popularity, and many apps running on Windows these days benefit from its features. Due to easy interoperability with Win32 APIs and backward compatibility, WPF is still a popular choice.&lt;/p&gt;

&lt;p&gt;Building a WPF video calling app with &lt;a href="https://dyte.io/video-sdk"&gt;Dyte SDK&lt;/a&gt; will be a two-step process. To use the same features available on Dyte SDK, we will use the &lt;a href="https://docs.dyte.io/ui-kit"&gt;Web Components&lt;/a&gt; and render those in WPF applications. To achieve this, in the first step, we will create a Web App with Dyte SDK, and in the second step, we will use &lt;a href="https://developer.microsoft.com/en-us/microsoft-edge/webview2/"&gt;Microsoft Edge WebView2&lt;/a&gt; to integrate the web app and render Dyte video calls. &lt;/p&gt;

&lt;p&gt;This will give us the best of both worlds. The awesomeness of WPF and developer-friendly &lt;a href="http://dyte.io/video-sdk"&gt;live video SDK&lt;/a&gt; from Dyte! The complete sample with two projects is available on GitHub &lt;a href="https://github.com/dyte-io/wpf-samples"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s begin to write some code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Building a Web App
&lt;/h2&gt;

&lt;p&gt;Create a Web Application using any tool that allows you to create an HTML file and run it on Live Server! In our sample, we are calling it ‘&lt;a href="https://github.com/dyte-io/wpf-samples/tree/main/solution-webapp"&gt;solution-webapp&lt;/a&gt;’&lt;/p&gt;

&lt;p&gt;In the HTML, refer to Dyte Web Components SDK and define custom elements:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
    import { defineCustomElements } from 'https://cdn.jsdelivr.net/npm/@dytesdk/ui-kit/loader/index.es2017.js';
    defineCustomElements();
&amp;lt;/script&amp;gt;
&amp;lt;script src='https://cdn.dyte.in/core/dyte.js'&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once you refer to the SDKs, you should be able to create a &lt;code&gt;dyte-meeting&lt;/code&gt;&lt;a href="https://docs.dyte.io/ui-kit/components/dyte-meeting"&gt;component&lt;/a&gt; that can render the meeting on the browser.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
   &amp;lt;dyte-meeting id="my-meeting" /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Initializing a meeting, joining the meeting, and getting notified whenever some event occurs e.g., recording status changes or someone joining or leaving a meeting, can be done using the following script.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
        //Pass roomName and authToken as query string parameters to this web page to join the meeting
        const searchParams = new URL(window.location.href).searchParams;
        const authToken = searchParams.get('authToken');
        //Initialize DyteClient -&amp;gt; A Dyte Meeting
        DyteClient.init({
            authToken
        }).then((meeting) =&amp;gt; {

        //Join the meeting room
        meeting.joinRoom();
        //Set participant tile to self i.e. display your own video in participant view    
        document.getElementById('my-meeting').meeting = meeting;
        });  
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The last two lines are important. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;meeting.joinRoom();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line of code will join the meeting and add or admit current participants (bearing the authToken) into the meeting.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;document.getElementById('my-meeting').meeting = meeting;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line of code will set the current ongoing meeting to the &lt;code&gt;dyte-meeting&lt;/code&gt;&lt;a href="https://docs.dyte.io/ui-kit/components/dyte-meeting"&gt;component&lt;/a&gt; we created before.&lt;/p&gt;

&lt;p&gt;You can run this HTML file using Live Server and test it. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_fdgGZv---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dyte.io/blog/content/images/size/w1000/2023/03/iMAGE---2--1-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_fdgGZv---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dyte.io/blog/content/images/size/w1000/2023/03/iMAGE---2--1-.png" alt="wpf video calling app demo" width="880" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Microsoft Edge WebView2
&lt;/h2&gt;

&lt;p&gt;Microsoft Edge uses the popular Chromium engine under the hood. It provides the same features and rendering capabilities as Chrome or other browsers. Apart from that, Microsoft has added features to improve productivity and performance on top of it. Microsoft Edge WebView2 is a component or control that brings the same Chromium experience to WPF apps. Navigate to &lt;a href="https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section"&gt;WebView2 - Microsoft Edge Developer&lt;/a&gt; and install the latest version. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Building a WPF Video Calling App
&lt;/h2&gt;

&lt;p&gt;To build a WPF app, you’ll need a Visual Studio setup. You can use different versions or editions and get started with it. Navigate to File &amp;gt; New &amp;gt; Project and create a new WPF app.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_hJe393--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/CUwFSDvwE3uwsEoQ3HlFC4pwCb-OIr06_ucEBNa24R7M6btkLTTRBbScUIE5NiCcgGnNIJRCok3n1okybkaK7mw599eXsQxlspWIejTJ03J6lU8di4NkX63mxk08Kw1WR7PtPTj8SKj43vaEjisV3_U" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_hJe393--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/CUwFSDvwE3uwsEoQ3HlFC4pwCb-OIr06_ucEBNa24R7M6btkLTTRBbScUIE5NiCcgGnNIJRCok3n1okybkaK7mw599eXsQxlspWIejTJ03J6lU8di4NkX63mxk08Kw1WR7PtPTj8SKj43vaEjisV3_U" alt="building wpf video calling app" width="880" height="586"&gt;&lt;/a&gt;&lt;br&gt;
Give this project a name; we’ve used ‘&lt;a href="https://github.com/dyte-io/wpf-samples/tree/main/solution-wpfapp"&gt;solution-wpfapp&lt;/a&gt;’ in the current sample. Use the .NET 6 or 7 version. &lt;/p&gt;

&lt;h3&gt;
  
  
  Refer NuGet Package
&lt;/h3&gt;

&lt;p&gt;Now we need to refer to WebView2 in this project. Click on Project &amp;gt; Manage NuGet Packages and search for Edge WebView 2 control. Once found, install it:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P-kLw4Pm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/ZL0M1xagENOVz_BurS5bkzANqS_QvoOWf_yoH1-xO-B4zjuA3QQBSdhWGmETfb4t79zwFf3dV6sxJZkozS4rUMMqEojQRzmdK0-pe4jflf_2_H0t-lfuBb60jGSyk4xelsaphQKiLI0wvoPEYWAtt2I" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P-kLw4Pm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/ZL0M1xagENOVz_BurS5bkzANqS_QvoOWf_yoH1-xO-B4zjuA3QQBSdhWGmETfb4t79zwFf3dV6sxJZkozS4rUMMqEojQRzmdK0-pe4jflf_2_H0t-lfuBb60jGSyk4xelsaphQKiLI0wvoPEYWAtt2I" alt="NuGet package" width="880" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the NuGet package is added, we can use Microsoft Edge WebView2 in our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refer to Component &amp;amp; Design UI
&lt;/h3&gt;

&lt;p&gt;Let’s create &lt;code&gt;ExamWindow&lt;/code&gt; as a separate XAML Window and add a reference to the added package.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Using the WebView2 component will be the same as using any other component.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;wpf:WebView2 Name="ParticipantWebView" Width="600" Height="300" Margin="20" DefaultBackgroundColor="AliceBlue"  /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We will use the following layout for this sample. However, feel free to design your interface as per your requirement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Pginxrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/B5e3lWPfkBX6BxKrv2t2qUUoAX5N4XMJq_ruWZzZJg1QEFwsPh_NbL0Bp0_z37YPtuJs5F9TtgxelaWVNJrE4JEJofkyLi2G5Hp9RALXpzL6FUjkIx3aWij0uyF4cGsax-9tJ2Wr4lCMRE32oeE0W8w" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Pginxrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/B5e3lWPfkBX6BxKrv2t2qUUoAX5N4XMJq_ruWZzZJg1QEFwsPh_NbL0Bp0_z37YPtuJs5F9TtgxelaWVNJrE4JEJofkyLi2G5Hp9RALXpzL6FUjkIx3aWij0uyF4cGsax-9tJ2Wr4lCMRE32oeE0W8w" alt="video calling app layout" width="880" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like we Initialise DyteMeeting, we need to Initialise the ExamWindow - a XAML window in the WPF app. We do so using the following code snippet. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ExamWindow()
{
     InitializeComponent();
     Loaded += ExamWindowLoaded;
     InitializeAsync();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We also need to Initialise the Edge WebView2 component, which we do in the code snippet as displayed below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async void InitializeAsync()
{
     await ParticipantWebView.EnsureCoreWebView2Async(null);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When the ExamWindow is Loaded, we set the HTML page URL we created and launched in Step 1. And we also pass the authToken so that a participant is added to the meeting.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void ExamWindowLoaded(object sender, RoutedEventArgs e)
{
     var host = string.Empty;        //Example: http://127.0.0.1:5500";
     var url = string.Empty;         //Example: index.html;
     var authToken = string.Empty;   //Example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjViMDZkNmY4LWM2M2YtNDA5Ny05ZmYwLTU4NzdmZmJmOTFiZiIsImxvZ2dlZEluIjp0cnVlLCJpYXQiOjE2NzIwMjc4NzksImV4cCI6MTY4MDY2Nzg3OX0.rvme95rRweh8ntafl042wMITiYQ4DLNuApHlarDg8A-4qU5r2q1Lg-B7Ev3rOWerXnhrlr0bIHC7wSq9gGBmfLhJvNJn3mtS1ief004YfpKpxAfnOhkVk8oRAcgBrmJxhVEZuxPQvD3--aEbdkRctqHo9z0JfZCnE2PaCPDa2uYOQhf4sFfORGfbTjPtdjs3FsR2gmSIu-nY0hHW3uStfuccA7s04gXy7-u9yVr18ibOColszxe4EONRyfV2uiouXZutCD_T6u9YMukk3RxkmK5LI7eFzWsc_gUmrpUahKoThmvh8PeiHwOSzWJd-BsJFHHPpKe0ivQIhg;
     var source = new Uri(string.Concat(host, "/", url, "?", "&amp;amp;authToken=", authToken));
     ParticipantWebView.Source = new Uri(source.ToString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Wiring Events &amp;amp; Setup Communication
&lt;/h2&gt;

&lt;p&gt;In this video calling app sample, we would want to send &lt;a href="https://docs.dyte.io/web-core/local-user/events"&gt;events&lt;/a&gt; to WPF app e.g. when someone joins a meeting or when the recording starts or a meeting ends. Similarly, we would like to send chat messages as well. To accomplish this, we will use events exposed by WebView in the browser and subscribe to those events in the WPF app. &lt;/p&gt;

&lt;p&gt;Let’s modify HTML to incorporate those events. We will add the following code snippet before we call &lt;code&gt;joinRoom();&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Attach meeting object to window object of the browser
window.meeting = meeting;
//Subscribe to events emitted by Dyte meeting.
meeting.recording.on('recordingUpdate', (e) =&amp;gt; {
    window.chrome.webview?.postMessage("recordingUpdate:" + e);
});
meeting.self.on('roomJoined', () =&amp;gt; {
    window.chrome.webview?.postMessage("roomJoined");
});
meeting.self.on('roomLeft', () =&amp;gt; {
    window.chrome.webview?.postMessage("roomLeft");
});
meeting.chat.on('chatUpdate', ({ message, messages }) =&amp;gt; {
    window.chrome.webview?.postMessage(message);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once we set up these event handlers, the event will send messages to the WPF app and we need to subscribe to those. We also want to send messages to the Web from WPF. So, let’s add the following event subscriptions to the constructor.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ParticipantWebView.WebMessageReceived += ParticipantWebViewWebMessageReceived;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, whenever an event is raised, the WPF app will receive a message and it will be displayed in a MessageBox.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void ParticipantWebViewWebMessageReceived(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs e)
{
     MessageBox.Show(e.WebMessageAsJson);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Lastly, we want to send chat messages to the meeting, we will do so when the button is clicked.&lt;/p&gt;

&lt;p&gt;Before that, let’s add a Button and a TextBox in UI&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TextBox Name="ChatMessage" Padding="5"/&amp;gt;
&amp;lt;Button Name="SendMessage" Padding="5"&amp;gt; Send Message &amp;lt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we can wire up the button clicked event which will send a chat message in a meeting.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void SendMessageClick(object sender, RoutedEventArgs e)
{
     ParticipantWebView.ExecuteScriptAsync($"meeting.chat.sendTextMessage('{ChatMessage.Text}');");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That’s pretty much what the app is all about. &lt;/p&gt;

&lt;p&gt;Testing this app is again a 2-step process. &lt;/p&gt;

&lt;p&gt;Step 1: Make sure the solution-webapp is running. Note down the URL. If the URL is different, make note of it and make changes in the WPF app. &lt;/p&gt;

&lt;p&gt;Step 2: launch the WPF app. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ol_MC364--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dyte.io/blog/content/images/size/w1000/2023/03/iMAGE---1-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ol_MC364--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dyte.io/blog/content/images/size/w1000/2023/03/iMAGE---1-1.png" alt="video calling app" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With Microsoft Edge WebView2 control, we can bring Dyte video calling to WPF apps and still use the richness of the framework. And there you have it — your own WPF video calling app built using the &lt;a href="https://dyte.io/video-sdk"&gt;Dyte SDK&lt;/a&gt;. Do check out the sample available here: &lt;a href="https://github.com/dyte-io/wpf-samples"&gt;https://github.com/dyte-io/wpf-samples&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>wpf</category>
      <category>video</category>
      <category>webrtc</category>
    </item>
  </channel>
</rss>
