#Region "LICENSE"
'
' Copyright (c) Microncode.com
' 
' This source is subject to the Microsoft Public License. 
' See https://opensource.org/licenses/ms-pl.html.
' All other rights reserved. 
' 
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
' WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
'
#End Region

Imports CSMediaProperties
Imports CSWebCam
Imports System
Imports System.Diagnostics
Imports System.Windows.Forms

Namespace CSWebCamExample

    ''' <summary>
    ''' The main example of using the CSWebCam with Winform.
    ''' </summary>
    Public Partial Class frmMain
        Inherits Form

        ''' <summary>
        ''' Create new instance of the component
        ''' </summary>
        Private _Camera As Camera = New Camera()


        ''' <summary>
        ''' Constructor.
        ''' </summary>
        Public Sub New()
            Me.InitializeComponent()

            'Events
            AddHandler _Camera.OperationOutput, New Camera.OperationOutputEventHandler(AddressOf OperationOutput)
            AddHandler _Camera.OperationDone, New Camera.OperationDoneEventHandler(AddressOf OperationDone)
            AddHandler _Camera.OperationStart, New Camera.OperationStartEventHandler(AddressOf OperationStart)
            AddHandler _Camera.OperationError, New Camera.OperationErrorEventHandler(AddressOf OperationError)
            AddHandler _Camera.OperationClosed, New Camera.OperationClosedEventHandler(AddressOf OperationClosed)
        End Sub


        ''' <summary>
        ''' Open local camera.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub cmdOpenCam_Click(ByVal sender As Object, ByVal e As EventArgs)
            CloseAll()
            _Camera.VideoResolutionX = Me.txtVideoResolutionX.Text
            _Camera.VideoResolutionY = Me.txtVideoResolutionY.Text

            'Set the FPS
            _Camera.VideoFPS = "30"

            'Buffer size:
            _Camera.BufferSize = "100MB"

            'In the MS camera I had to add this 
            'in order to display the camera
            _Camera.DispWinPixFmt = "yuv420p"

            'Set the preview
            _Camera.SetPicView(Me.cameraPreviewWF1.Preview)

            'Open the device
            _Camera.OpenDevice(Me.cboCamDevices.Text, Me.cboAudioDevices.Text)
        End Sub


        ''' <summary>
        ''' Close the camera.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub cmdCloseCam_Click(ByVal sender As Object, ByVal e As EventArgs)
            'Close the camera
            _Camera.Close()
        End Sub


        ''' <summary>
        ''' Form_Load.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Async Sub frmMain_Load(ByVal sender As Object, ByVal e As EventArgs)
            'Create a new instance of the library with the direction of the ffmpeg libraries

            Try
                'Set the path of the ffmpeg libraries
                Dim LibsPath As String = ""

                'If the LibsPath is empty or "" the library will search for
                'the ffmpeg libraries under the path:
                '[AssemblyDirectory]\CSPlugins\FFmpeg\[x86|x64]\

                Await _Camera.Init("UserName", "RegKey", LibsPath)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                Return
            End Try


            'Get all the video / camera devices
            For Each videoDevice In _Camera.CameraDevices
                Me.cboCamDevices.Items.Add(videoDevice.Name)
            Next


            'Select the first
            Me.cboCamDevices.SelectedIndex = 0


            'Get all the audio devices
            For Each audioDevice In _Camera.AudioDevices
                Me.cboAudioDevices.Items.Add(audioDevice.Name)
            Next


            'Select the first
            Me.cboAudioDevices.SelectedIndex = 0

            'Select MP4 format
            Me.cboDestinationFormat.Text = "MP4"
        End Sub


        ''' <summary>
        ''' Form_Closing.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
            CloseAll()
            _Camera.KillAllProcesses()
        End Sub


        ''' <summary>
        ''' Close all instances of the FFmpeg.
        ''' </summary>
        Public Sub CloseAll()
            If _Camera.IsRun Then
                _Camera.Close()

                While _Camera.IsRun

                    Try
                        Application.DoEvents()
                        Threading.Thread.Sleep(50)
                    Catch __unusedException1__ As Exception
                    End Try
                End While
            End If
        End Sub


        ''' <summary>
        ''' Capture the camera to a video / audio file.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub cboCapture_Click(ByVal sender As Object, ByVal e As EventArgs)
            Dim saveFileDialog1 As SaveFileDialog = New SaveFileDialog()
            saveFileDialog1.Filter = "AVI|*.avi|FLV|*.flv|MKV|*.mkv|MOV|*.mov|MP4|*.mp4|MTS|*.mts|MPEG|*.mpeg|WEBM|*.webm|WMV|*.wmv"
            saveFileDialog1.Title = "Save As File"
            saveFileDialog1.FilterIndex = Me.cboDestinationFormat.SelectedIndex + 1
            saveFileDialog1.ShowDialog()

            If Not Equals(saveFileDialog1.FileName, "") Then
                CloseAll()

                'Set the video format
#Region "VideoFormat"

                _Camera.VideoResolutionX = Me.txtVideoResolutionX.Text
                _Camera.VideoResolutionY = Me.txtVideoResolutionY.Text

                'Set the FPS
                _Camera.VideoFPS = "30"

                'Set the buffer size
                _Camera.BufferSize = "100MB"

                'In the MS camera I had to add this 
                'in order to display the camera
                _Camera.DispWinPixFmt = "yuv420p"

                'Set more properties of the 
                'destination video
                '_Camera.VideoBitrate = "316k";
                '_Camera.VideoCodec = "...";
                'Audio:
                '_Camera.AudioCodec = "...";
                '_Camera.AudioBitrate = "128k";
                '_Camera.AudioSamplerate = "44100";
                '_Camera.AudioChannels = "2";

#End Region

                'Set the ID3 Tags
#Region "ID3Tags"

                Dim iD3Tags As ID3Tags = New ID3Tags()
                iD3Tags.Title = "Title"
                iD3Tags.Comment = "Comment"
                iD3Tags.Album = "Album"
                iD3Tags.Artist = "Artist"
                iD3Tags.Date = "2020"
                _Camera.SetID3Tags(iD3Tags)

#End Region

                'Set the preview
                _Camera.SetPicView(Me.cameraPreviewWF1.Preview)

                'Open the device and save the results to a media file
                _Camera.OpenDevice(Me.cboCamDevices.Text, Me.cboAudioDevices.Text, saveFileDialog1.FileName)
            End If
        End Sub


        ''' <summary>
        ''' Stop capture.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub cboStopCapture_Click(ByVal sender As Object, ByVal e As EventArgs)
            _Camera.Close()
        End Sub


        ''' <summary>
        ''' Get the details of the selected camera device.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Async Sub cboCamDeviceDetails_Click(ByVal sender As Object, ByVal e As EventArgs)
            MessageBox.Show(Await _Camera.GetDeviceOptionsVideo(Me.cboCamDevices.Text))
        End Sub


        ''' <summary>
        ''' Get the details of the selected audio device.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Async Sub cboAudioDeviceDetails_Click(ByVal sender As Object, ByVal e As EventArgs)
            MessageBox.Show(Await _Camera.GetDeviceOptionsAudio(Me.cboAudioDevices.Text))
        End Sub


#Region "Events"

        ''' <summary>
        ''' Operation out put.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="output"></param>
        ''' <paramname="props"></param>
        Public Sub OperationOutput(ByVal sender As Object, ByVal output As String, ByVal props As OutputProperties)
            'Display the output
            Debug.WriteLine(output)

            'Get the frame
            Debug.Print("Frame: " & props.Frame.ToString())

            'Get the FPS
            Debug.Print("FPS: " & props.Fps.ToString())

            'Get the speed
            Debug.Print("Speed: " & props.Speed.ToString())

            'Get the time
            Debug.Print("Time: " & props.Time.ToString())
        End Sub


        ''' <summary>
        ''' Operation done.
        ''' </summary>
        ''' <paramname="sender"></param>
        Public Sub OperationDone(ByVal sender As Object)
            'Operation done
        End Sub


        ''' <summary>
        ''' Operation started.
        ''' </summary>
        ''' <paramname="sender"></param>
        Public Sub OperationStart(ByVal sender As Object)
            'Operation started
        End Sub


        ''' <summary>
        ''' On Error.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="output"></param>
        Public Sub OperationError(ByVal sender As Object, ByVal output As String)
            'Error:
            MessageBox.Show(output)
        End Sub


        ''' <summary>
        ''' Operation closed.
        ''' </summary>
        ''' <paramname="sender"></param>
        Public Sub OperationClosed(ByVal sender As Object)
            'OperationClosed
        End Sub


#End Region

        ''' <summary>
        ''' Order a license.
        ''' </summary>
        ''' <paramname="sender"></param>
        ''' <paramname="e"></param>
        Private Sub cmdOrderLicense_Click(ByVal sender As Object, ByVal e As EventArgs)
            ''' In order to get your own UserName and RegKey and to distribute this library
            ''' with your own projects for commercial or any other purpose, please order a license at:
            ''' https://www.microncode.com/developers/cs-webcam/?cmd=order

            Process.Start("https://www.microncode.com/developers/cs-webcam/?cmd=order")
        End Sub
    End Class
End Namespace
