B4J Tutorial [Server] CCTV Server

Discussion in 'B4J Tutorials' started by Erel, Feb 2, 2014.

  1. Erel

    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:
    Public Sub Handle(req As ServletRequest, resp As ServletResponse)
    Dim out As OutputStream
    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)
    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:
    Sub Process_Globals
    Private srvr As Server
    Public images As Map
    End Sub

    Sub AppStart (Args() As String)
       srvr.Port = 
       images = srvr.CreateThreadSafeMap
    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":
    Public Sub Handle(req As ServletRequest, resp As ServletResponse)
    For Each ip As String In Main.images.Keys
    "<img width=500 height=300 src='/GetImage?IP=" & ip & "&avoidcache=" & DateTime.Now & "'/>")
    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:
    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.

    Attached Files:

    Last edited: Feb 3, 2014
    asales, Peter Simpson and RayLee like this.
  2. derez

    derez Expert Licensed User

    Looks great, I can't wait !
  3. Erel

    Erel Administrator Staff Member Licensed User

    Thank you.
    The missing feature in beta 2 is Map.Values / Keys for thread safe maps.

    I plan to release v1.50 (stable) tomorrow.
    gudino jose luis likes this.
  4. Erel

    Erel Administrator Staff Member Licensed User

    gudino jose luis likes this.
  5. Alexandre Riani

    Alexandre Riani Member Licensed User


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

    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?

  6. Erel

    Erel Administrator Staff Member Licensed User

  7. microbox

    microbox Active Member Licensed User

    Hi.. just a question here. If I entered http:\\ 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: Jun 18, 2014
  8. LucaMs

    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.
  9. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this question.
  10. LucaMs

    LucaMs Expert Licensed User

    Sorry, you're right
  11. Toley

    Toley Active Member Licensed User

    Hi Erel can this be used to stream pictures from a Raspberry Pi camera?
  12. Erel

    Erel Administrator Staff Member Licensed User

    The challenge is to capture the picture on the Raspberry Pi. If you are able to capture it then you can also stream it to the server.

    Please start a new thread for this.
  13. alexhi

    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
    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\

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

    Thank you.
  14. Erel

    Erel Administrator Staff Member Licensed User

    Make sure that #MergeLibraries attribute is set to True.
    alexhi likes this.
  15. alexhi

    alexhi Member Licensed User

    Thank you, work OK.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice