// MainWindow.xaml

<Window x:Class="Basic_CameraViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="550" Width="550" 
        ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
    <Grid>
        <GroupBox Header="Connect to USB camera" Height="100" Width="150"
                  HorizontalAlignment="Left" VerticalAlignment="Top">
            <Grid>
                <Button Content="Connect" Width="75" Margin="32,19,0,0" 
                        HorizontalAlignment="Left" VerticalAlignment="Top"
                        Click="ConnectUSBCamera_Click"/>
                <Button Content="Disconnect" Width="75" Margin="32,46,0,0"
                        HorizontalAlignment="Left" VerticalAlignment="Top"
                        Click="DisconnectUSBCamera_Click"/>
            </Grid>
        </GroupBox>

        <Grid Name="CameraBox" Margin="10,105,10,166"/>

        <GroupBox Header="Function" Height="160" Width="542" Margin="0,360,0,0"
                  HorizontalAlignment="Left" VerticalAlignment="Top" >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <ListBox Grid.Column="1" Name="ConnectedClientList"/>
                <GroupBox Grid.Column="0" Header="Set Listen Address">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="3*"/>
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Content="Address"/>
                            <TextBox Grid.Column="1" Height="25" Name="IpAddressText"/>
                        </Grid>
                        <Grid Grid.Row="1">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="3*"/>
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Content="Port"/>
                            <TextBox Grid.Column="1" Height="25" Name="PortText"/>
                        </Grid>
                        <Grid Grid.Row="2">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Button Grid.Column="0" Content="Start" 
                                    HorizontalAlignment="Center" VerticalAlignment="Center" 
                                    Width="75" Click="StartServer_Click"/>
                            <Button Grid.Column="1" Content="Stop" 
                                    HorizontalAlignment="Center" VerticalAlignment="Center" 
                                    Width="75" Click="StopServer_Click" />
                        </Grid>
                    </Grid>
                </GroupBox>
            </Grid>
        </GroupBox>
    </Grid>
</Window>

// MainWindow.xaml.cs
            
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ozeki.Media.IPCamera;
using Ozeki.Media.MediaHandlers;
using Ozeki.Media.MediaHandlers.Video;
using Ozeki.Media.MJPEGStreaming;
using Ozeki.Media.Video.Controls;

namespace Basic_CameraViewer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private VideoViewerWPF _videoViewerWpf;

        private BitmapSourceProvider _provider;

        private IIPCamera _ipCamera;

        private WebCamera _webCamera;

        private MediaConnector _connector;

        private MyServer _server;

        private IVideoSender _videoSender;

        public MainWindow()
        {
            InitializeComponent();

            _connector = new MediaConnector();

            _provider = new BitmapSourceProvider();

            _server = new MyServer();

            SetVideoViewer();
        }

        private void SetVideoViewer()
        {
            _videoViewerWpf = new VideoViewerWPF
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
                Background = Brushes.Black
            };
            CameraBox.Children.Add(_videoViewerWpf);

            _videoViewerWpf.SetImageProvider(_provider);
        }

        #region USB Camera Connect/Disconnect

        private void ConnectUSBCamera_Click(object sender, RoutedEventArgs e)
        {
            _webCamera = WebCamera.GetDefaultDevice();
            if (_webCamera == null) return;
            _connector.Connect(_webCamera, _provider);
            _videoSender = _webCamera;

            _webCamera.Start();
            _videoViewerWpf.Start();
        }

        private void DisconnectUSBCamera_Click(object sender, RoutedEventArgs e)
        {
            if (_webCamera == null) return;
            _videoViewerWpf.Stop();

            _webCamera.Stop();
            _webCamera.Dispose();

            _connector.Disconnect(_webCamera, _provider);
        }
        #endregion

        private void GuiThread(Action action)
        {
            Dispatcher.BeginInvoke(action);
        }

        private void StartServer_Click(object sender, RoutedEventArgs e)
        {
            var ipadress = IpAddressText.Text;
            var port = int.Parse(PortText.Text);
            _server.VideoSender = _videoSender;

            _server.OnClientCountChanged += server_OnClientCountChanged;

            _server.Start();
            _server.SetListenAddress(ipadress, port);
        }

        void server_OnClientCountChanged(object sender, EventArgs e)
        {
            GuiThread(() =>
            {
                ConnectedClientList.Items.Clear();

                foreach (var client in _server.ConnectedClients)
                    ConnectedClientList.Items.Add("End point: " +
                        client.TransportInfo.RemoteEndPoint);
            });
        }

        private void StopServer_Click(object sender, RoutedEventArgs e)
        {
            _server.OnClientCountChanged -= server_OnClientCountChanged;
            _server.Stop();
        }
    }
}