B4J Tutorial [Server] CCTV Server

Erel

Administrator
Staff member
Licensed User
In a previous example we shown you how you can use B4J to create a desktop application that connects to a number of devices and shows the camera frames: B4J CCTV example

In this example we implement a similar solution, however using the server framework the network related code is much simpler and as this is a server solution you can connect to the server from anywhere you like and see the camera frames inside the browser:




The device code is very similar to the code used in the other example. The only difference is that HttpUtils2 is used to send the images (instead of a Socket + AsyncStreams).

The server project is made of three handlers:
SendImage - The devices call this handler with the cameras frames. This handler then stores the image data in a process global Map named images:
B4X:
Public Sub Handle(req As ServletRequest, resp As ServletResponse)
   Dim out As OutputStream
   out.InitializeToBytesArray(0)
   File.Copy2(req.InputStream, out) 'read the image from the input stream and write it into a memory stream
   Main.images.Put(req.RemoteAddress, out.ToBytesArray)
   resp.Write("Ok")
End Sub
The device IP address is used as the key.

Main.images is a special Map. It is created in the Main module code:
B4X:
Sub Process_Globals
   Private srvr As Server
   Public images As Map
End Sub

Sub AppStart (Args() As String)
   srvr.Initialize("")
   srvr.Port = 51042
   srvr.AddHandler("/SendImage", "SendImage", False)
   srvr.AddHandler("/GetImages", "GetImages", False)
   srvr.AddHandler("/GetImage", "GetImage", False)
   srvr.Start
   images = srvr.CreateThreadSafeMap
   StartMessageLoop
End Sub
Server.CreateThreadSafeMap returns a special Map that can be safely accessed by multiple threads. This is very useful for all kinds of cache implementations.

GetImages - This handler creates a simple html that includes the images "urls":
B4X:
Public Sub Handle(req As ServletRequest, resp As ServletResponse)
   For Each ip As String In Main.images.Keys
     resp.Write("<p>").Write(ip).Write("</p>")
     resp.Write("<img width=500 height=300 src='/GetImage?IP=" & ip & "&avoidcache=" & DateTime.Now & "'/>")
   Next
End Sub
As you can see in the img src value the images are actually handled by another handler named GetImage.
Note that a time based parameter is added. The parameter value will be different on each request. This way we force the browser to redownload the images.

GetImage - Returns a stored image based on the IP parameter:
B4X:
Public Sub Handle(req As ServletRequest, resp As ServletResponse)
   Dim ip As String = req.GetParameter("IP")
   Dim img() As Byte = Main.images.Get(ip)
   Dim In As InputStream
   In.InitializeFromBytesArray(img, 0, img.Length)
   File.Copy2(In, resp.OutputStream)
End Sub

How it all connects

The main page (index.html file) uses ajax requests to refresh one of the "divs" every 500ms. This is done with the GetImages handler. Later as a result of the img src values the GetImage handler is called for each image url and returns the most recent image based on the specified IP address.

Note that the server should be able to handle a large number of connected devices. Probably more than 50 or 100.
 

Attachments

Last edited:

Xandoca

Active Member
Licensed User
Hi,

Client app is closed after the following code with no errors (just open the app with no interaction):

B4X:
r.RunMethod4("compressToJpeg", Array As Object(rect1, quality, out), _
        Array As String("android.graphics.Rect", "java.lang.int", "java.io.OutputStream"))
I've put try catch but log(lastexception.message) didn't show any error.

My device is a samsung GT-I5510 with Android 2.3.7

Any clues?

Tks
Riani
 

microbox

Active Member
Licensed User
Hi.. just a question here. If I entered http:\\127.0.0.1:51042 to the url should display the video from the android device...right? I'm getting only CCTV Server on the page, I'm not sure what I'm missing. I tried the B4J desktop CCTV version and works great. But I really like the idea of this version.

Edited: I got it to work...it was the ip address. :)
 
Last edited:

LucaMs

Expert
Licensed User
Since I do not know JQuery, for me the short function in the Index.html is hard: could someone put a simple access control (without db, simply a clear pw in some handler/filter class)?

Many thanks.
 

alexhi

Member
Licensed User
Sorry my Eng.
If I start CCTVServer in IDE (B4j) work OK.

If I start :
java -jar CCTVServer.jar

I see error in log:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: anywheresoftware/b4a
BA
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: anywheresoftware.b4a.BA
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 7 more

I have install c:\Program Files\Java\
jdk1.8.0_65
jdk1.8.0_77
jre1.8.0_77

Path Config (IDE)
C:\Program Files\Java\jdk1.8.0_77\bin\javac.exe

Thank you.
 
Top