Video Application

This forum is for eXpress++ general support.
Post Reply
Message
Author
User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Video Application

#1 Post by rdonnay »

Here is a sample application that uses the VideoCapX ActiveX control.

I have a customer application (written in Xbase++) that controls the world's most sensitive metal detector.
The Xbase++ app communicates with 2 microprocessors via IP to control scanning the user's access card, reading the electric field of the arch, opening the door, displaying graphs and charts, etc.

What it didn't do (until now) is capture a video of persons entering the arch.
Here's the test code. Now I only need to add it to the application. Works great!!!

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "videocapx.CH"

FUNCTION Main()

LOCAL GetList[0], oVideo1, oVideo2, GetOptions, oTimer

PUBLIC oVideo

@ 0,0 DCACTIVEXCONTROL oVideo1 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 330, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:capFileName := '.\Camera1\' + Dtos(Date())+'_'+Strtran(Time(),':','-')+'.Avi', ;
                oVideo1:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo1:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera1\','.jpg'),XBPBMP_FORMAT_JPG)}


@ 360,0 DCACTIVEXCONTROL oVideo2 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 700, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:capFileName := GetFileName('.\Camera2\','.Avi'), ;
                oVideo2:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo2:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera2\','.jpg'),XBPBMP_FORMAT_JPG)}


DCGETOPTIONS RESIZE RESIZEDEFAULT DCGUI_RESIZE_AUTORESIZE

DCREAD GUI FIT TITLE 'VideoCapX Sample Program' ;
   OPTIONS GetOptions ;
   EVAL {|o|oVideo2:DebugMode := 1, ;
            oVideo2:UseVideoFilter := vcxBoth, ;
            oVideo2:PreviewAudio := .f., ;
            oVideo2:VideoDeviceIndex := 1, ;
            oVideo2:Connected := .t., ;
            oVideo2:Preview := .t., ;
            oVideo1:DebugMode := 1, ;
            oVideo1:UseVideoFilter := vcxBoth, ;
            oVideo1:PreviewAudio := .f., ;
            oVideo1:VideoDeviceIndex := 0, ;
            oVideo1:Connected := .t., ;
            oVideo1:Preview := .t., ;
            M->oVideo := oVideo1, ;
            oTimer := DC_SetTimerEvent():new(100,{||CheckForMotion(oVideo1,oVideo2)}), ;
            nil }

oTimer:destroy()

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION GetFileName( cPath, cExt )

RETURN cPath + Dtos(Date())+'_'+Strtran(Time(),':','-') + cExt

* ---------

STATIC FUNCTION CheckForMotion( oVideo1, oVideo2 )

IF oVideo1:isCapturing .AND. oVideo1:DetectMotion() < 3
  oVideo1:stopCapture()
  DC_SpawnUrl(oVideo1:capFileName)
ELSEIF !oVideo1:isCapturing .AND. oVideo1:DetectMotion() >= 5
  oVideo1:capFileName := GetFileName('.\Camera1\','.Avi')
  oVideo1:startCapture()
ENDIF

IF oVideo2:isCapturing .AND. oVideo2:DetectMotion() < 3
  oVideo2:stopCapture()
  DC_SpawnUrl(oVideo2:capFileName)
ELSEIF !oVideo2:isCapturing .AND. oVideo2:DetectMotion() >= 5
  oVideo2:capFileName := GetFileName('.\Camera2\','.Avi')
  oVideo2:startCapture()
ENDIF

RETURN nil

* ------------

STATIC FUNCTION GetBitmapFromClipBoard()

LOCAL oClipBoard, oBitmap

oClipBoard := XbpClipBoard():new():create()
oClipBoard:open()
oBitMap := oClipBoard:getBuffer( XBPCLPBRD_BITMAP )
oClipBoard:close()

RETURN oBitmap
Attachments
Video.zip
(22.65 KiB) Downloaded 688 times
The eXpress train is coming - and it has more cars.

User avatar
digitsoft
Posts: 461
Joined: Thu Jan 28, 2010 1:33 pm
Location: Republica Dominicana
Contact:

Re: Video Application

#2 Post by digitsoft »

rdonnay wrote:Here is a sample application that uses the VideoCapX ActiveX control.
Hi Roger
Error Automation/6500
description: Could not create ActiveX control
Thread ID: 1
Called Frim DC_XBPACTIVEXCONTROL:CREATE(5979)
Called Frim DC_GETLIST:CREATEOBJECT(12030)
Called Frim DC_GETLIST:READGUI(2294)
Called Frim DC_READGUI(109)
Called Frim MAIN(60)




I have a customer application (written in Xbase++) that controls the world's most sensitive metal detector.
The Xbase++ app communicates with 2 microprocessors via IP to control scanning the user's access card, reading the electric field of the arch, opening the door, displaying graphs and charts, etc.

What it didn't do (until now) is capture a video of persons entering the arch.
Here's the test code. Now I only need to add it to the application. Works great!!!

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "videocapx.CH"

FUNCTION Main()

LOCAL GetList[0], oVideo1, oVideo2, GetOptions, oTimer

PUBLIC oVideo

@ 0,0 DCACTIVEXCONTROL oVideo1 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 330, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:capFileName := '.\Camera1\' + Dtos(Date())+'_'+Strtran(Time(),':','-')+'.Avi', ;
                oVideo1:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo1:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera1\','.jpg'),XBPBMP_FORMAT_JPG)}


@ 360,0 DCACTIVEXCONTROL oVideo2 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 700, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:capFileName := GetFileName('.\Camera2\','.Avi'), ;
                oVideo2:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo2:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera2\','.jpg'),XBPBMP_FORMAT_JPG)}


DCGETOPTIONS RESIZE RESIZEDEFAULT DCGUI_RESIZE_AUTORESIZE

DCREAD GUI FIT TITLE 'VideoCapX Sample Program' ;
   OPTIONS GetOptions ;
   EVAL {|o|oVideo2:DebugMode := 1, ;
            oVideo2:UseVideoFilter := vcxBoth, ;
            oVideo2:PreviewAudio := .f., ;
            oVideo2:VideoDeviceIndex := 1, ;
            oVideo2:Connected := .t., ;
            oVideo2:Preview := .t., ;
            oVideo1:DebugMode := 1, ;
            oVideo1:UseVideoFilter := vcxBoth, ;
            oVideo1:PreviewAudio := .f., ;
            oVideo1:VideoDeviceIndex := 0, ;
            oVideo1:Connected := .t., ;
            oVideo1:Preview := .t., ;
            M->oVideo := oVideo1, ;
            oTimer := DC_SetTimerEvent():new(100,{||CheckForMotion(oVideo1,oVideo2)}), ;
            nil }

oTimer:destroy()

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION GetFileName( cPath, cExt )

RETURN cPath + Dtos(Date())+'_'+Strtran(Time(),':','-') + cExt

* ---------

STATIC FUNCTION CheckForMotion( oVideo1, oVideo2 )

IF oVideo1:isCapturing .AND. oVideo1:DetectMotion() < 3
  oVideo1:stopCapture()
  DC_SpawnUrl(oVideo1:capFileName)
ELSEIF !oVideo1:isCapturing .AND. oVideo1:DetectMotion() >= 5
  oVideo1:capFileName := GetFileName('.\Camera1\','.Avi')
  oVideo1:startCapture()
ENDIF

IF oVideo2:isCapturing .AND. oVideo2:DetectMotion() < 3
  oVideo2:stopCapture()
  DC_SpawnUrl(oVideo2:capFileName)
ELSEIF !oVideo2:isCapturing .AND. oVideo2:DetectMotion() >= 5
  oVideo2:capFileName := GetFileName('.\Camera2\','.Avi')
  oVideo2:startCapture()
ENDIF

RETURN nil

* ------------

STATIC FUNCTION GetBitmapFromClipBoard()

LOCAL oClipBoard, oBitmap

oClipBoard := XbpClipBoard():new():create()
oClipBoard:open()
oBitMap := oClipBoard:getBuffer( XBPCLPBRD_BITMAP )
oClipBoard:close()

RETURN oBitmap
Nolberto Paulino
Regards

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Video Application

#3 Post by rdonnay »

You need to download and install the VideoCapX 30-day trial.

http://www.fathsoft.com/vctsetup.exe
The eXpress train is coming - and it has more cars.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Video Application

#4 Post by Auge_Ohr »

rdonnay wrote:What it didn't do (until now) is capture a video of persons entering the arch.
when using WebCam from Notebook you can access WM_CAP*** Event with ot4xb to capture Picture.
***http://msdn.microsoft.com/en-us/library ... S.85).aspx

more Info @ Pablos Website http://www.xbwin.com -> Forum

Who can help ?
ot4xb.public
28. April 2012
Jack Duijf

read Thread and see Attachments while there are 3 Solution.
here is my Version NEED ot4xb to compile !
WebCam.zip
Source NEED ot4xb
(245.87 KiB) Downloaded 649 times
greetings by OHR
Jimmy

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Video Application

#5 Post by rdonnay »

when using WebCam from Notebook you can access WM_CAP*** Event with ot4xb to capture Picture.
This is an eXpress++ forum.
It is intended to help eXpress++ users learn how to do new things in eXpress++, not ot4xb.
The eXpress train is coming - and it has more cars.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Video Application

#6 Post by Auge_Ohr »

rdonnay wrote:This is an eXpress++ forum.
It is intended to help eXpress++ users learn how to do new things in eXpress++, not ot4xb.
Yes ...
but Xbase++ is so limited without ot4xb in Windows World where you have all those DLL already
on your PC when install WDM Hardware and do not need to buy external activeX.

when you disable ONE line with ot4xb in my Demo Code it still work while it is pure Xbase++.
Jack Duijf had ask in Pablos Forum why he have to "move Mouse" to get Picture move ... hm.
he had reach limit of Xbase++ with his Code and only Solution was ot4xb

Code: Select all

    ::hHwnd := delegated_eval( {|| capCreateCaptureWindowA("CapWindow",;
                                       dwStyle               ,;
                                       0, 0, nWidth, nHeight ,;
                                       ::oStatic:getHWND()   ,;
                                       0 ) } )
so my Intend was to show what can be done if someone got in similar Situation when try to capture Video / Picture.
greetings by OHR
Jimmy

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Video Application

#7 Post by rdonnay »

This application had a requirement to show 2 video windows, (1 for each camera), and to capture the video to a file whenever there was motion detected. The ActiveX control that provides this capability costs $99 and easily integrates with Xbase++. eXpress++ developers do not consider a $99 expense to be excessive. They consider their time to be valuable and this takes almost none of their time. This is a nice "black box" solution. This control provides another 10 features that will be easily integrated into the application with a few lines of code.
Your solution would require that they learn a lot more new stuff. You still don't get it. Every time I post a solution to a problem using eXpress++, you followup with a posting about a solution that is more complicated and will consume more time.

I will remind you again that this forum is for eXpress++ users, NOT ot4xb.

If you really want to support eXpress++ users, then provide some source code that shows how to do this using the eXpress++ method. Make a screen using DC* commands and embed a video control using ot4xb. If you cannot do this then you are not helping.
The eXpress train is coming - and it has more cars.

User avatar
unixkd
Posts: 579
Joined: Thu Feb 11, 2010 1:39 pm

Re: Video Application

#8 Post by unixkd »

Thanks so much Roger.

You spoke my mind. Alaska added ActiveX support to Xbase++ because they know that will improve productivity immensely. Express++ developers have goals viz: productivity, maintainabily, robustness, reliability, functionality etc. and calling windows API achieve non of these goals. The learning curve for WIN API is very steep, I can tell you that. Majority of Express++ programmers we former clipper programmers without sound knowledge of C/C++ and Assembly languages. Roger understand this very perfectly if you study his wonderful approach to Express++.

ActiveX components extend Xbase++ functionalities and I will not waste my time creating those functionalities if I can buy them right away.

Roger Kudos to you !!!

Joe.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Video Application

#9 Post by Auge_Ohr »

rdonnay wrote:If you really want to support eXpress++ users, then provide some source code that shows how to do this using the eXpress++ method. Make a screen using DC* commands and embed a video control using ot4xb.
as you know i do not use Express++ only "pure" Xbase++ Class Code that every Express++ User can use.

to "that" one line of ot4xb Code, which you have used with Express++ / Codejock in FUNCTION CJ_SetAppFocus()

Code: Select all

  nDllHandle := DllLoad('ot4xb.dll')
  IF nDllHandle > 0
    &("Delegated_Eval")( {|| &("nFpCall")( {"user32","SetFocus"} , nHandle ) } )
  ELSE
    DC_WinAlert('CJ_SetAppFocus() requires ot4xb.dll')
  ENDIF
how can i write it better Code than you did already.

but back to Question as you say you have NOT try capture Picture from Stream : is it possible with that activeX ?

Xbase++ activeX are running in GUI Thread and i do had Problem with WMP > 9 to capture Picture from Stream.
Solution was Delegated_Eval, which Eval a codeblock at the GUI thread, as we have to use it with Codejock.
greetings by OHR
Jimmy

Post Reply