B4A Library [B4X] [class] MJPEG decoder

Discussion in 'Additional libraries, classes and official updates' started by Erel, Dec 1, 2016.

  1. Erel

    Erel Administrator Staff Member Licensed User

    The attached class is an implementation of a MJPEG over Http decoder.

    The data is a mix of strings and raw bytes.
    It is tempting to convert the bytes to a string. However raw bytes do not represent a valid string so you can lose important information during the conversion (which will also slow down the program).

    Edit: For new projects it is recommended to use BytesBuilder.

    The following sub is used to search for strings or bytes in the raw bytes directly:
    Private Sub IndexOfString(s As String, Start As Int) As Int
    Return IndexOf(s.GetBytes("ASCII"), Start)
    End Sub

    Private Sub IndexOf(bs() As Byte, Start As Int) As Int
    For i = Start To index - 1 - bs.Length
    For b = 0 To bs.Length - 1
    If bs(b) <> Data(i + b) Then Exit
    If b = bs.Length Then Return i
    Return -1
    End Sub
    The data is copied to a large array. Once a frame is found it is parsed and the array is trimmed using ByteConverter.ArrayCopy.

    It is compatible with B4i, B4A and B4J.

    upload_2016-12-1_18-18-56.png [​IMG]


    It works better in release mode.
    You will need to handle disconnections.

    Attached Files:

    Last edited: Jul 9, 2018
  2. adrianfreitas

    adrianfreitas Member Licensed User

    hum... I see... great lesson here, the data management is a bit more complex. My approach was translate it directly, a lack of knowledge, for sure.
    Thank you one more time, Erel,
  3. inakigarm

    inakigarm Well-Known Member Licensed User

    Changes for B4J: change bitmap object (B4A) to image (B4J) in Main code and Module (in AStream_NewSata Sub on MJPEG.BAS Module)

    #Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 400
    #End Region

    Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private Imgmjpeg As ImageView
    Public mjpeg1 As MJPEG
    End Sub

    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
    "lyprojmjpeg"'Load the layout file.
    End Sub

    Public Sub mjpeg_Frame(img As Image)
    End Sub

    '                Dim bmp As Bitmap
    '                bmp.Initialize2(In)
    '                CallSub2(mCallback, mEventName & "_frame", bmp)
                    Dim img As Image
    CallSub2(mCallback, mEventName & "_frame", img)

    DonManfred and Erel like this.
  4. Erel

    Erel Administrator Staff Member Licensed User

    A similar change, using conditional compilation, is available in the MJPEG.bas file that is attached to the first post.
    inakigarm likes this.
  5. inakigarm

    inakigarm Well-Known Member Licensed User

    Ok thanks, that's because I've downloaded only MJPEG.zip and modified the .Bas included on it (that doesn't include conditional compilation)
  6. adrianfreitas

    adrianfreitas Member Licensed User

    Writing my app, I realized that it does not working with other cameras. The IPs below, for example, work in both the browser and the implementations in VB6 and Xojo, but they are not working with this class. I tried some variations but it did not work out.
    Here are some IP's that did not work: ( ( (
  7. Erel

    Erel Administrator Staff Member Licensed User

    The url was not handled properly. I've uploaded a new version that fixes this issue. It is a B4J project. You can find the class file inside the zip.

    inakigarm and adrianfreitas like this.
  8. adrianfreitas

    adrianfreitas Member Licensed User

    Excelent as always!!
    By the way, I didn't know this syntax:
    $"GET ${mPath} HTTP/1.1
                Host: ${
                Connection: keep-alive
    One more learned... Thank you!
  9. tchart

    tchart Active Member Licensed User

    My security camera requires a user name and password. I cant see any way to pass this to the socket.

    Has anyone tried this with secure cameras?
  10. tchart

    tchart Active Member Licensed User

    Actually figured it out. You need to add this to the header;

    Dim sTmp As String = $"GET ${mPath} HTTP/1.1
    Host: ${
    Authorization:Basic ${
    Connection: keep-alive
    The token is a base64 encryption of username:password like this;

    Dim YOUR_USERNAME As String = "admin"
    Dim YOUR_PASSWORD As String = "mypassword"   
    Dim Token As String

    Dim Temp As String = YOUR_USERNAME & ":" & YOUR_PASSWORD
    Dim TempBytes() As Byte = Temp.GetBytes("UTF8")   
    Token = su.EncodeBase64(TempBytes)
    MarcoRome, sirjo66 and DonManfred like this.
  11. MarcoRome

    MarcoRome Expert Licensed User

    Hi, the link:

    work without problem.


    If i try in B4J dont work.


    Where i wrong ?
    Thank you
  12. Erel

    Erel Administrator Staff Member Licensed User

    Start a new thread in the questions forum and I'll explain the steps required to get it working.

    MarcoRome and Peter Simpson like this.
  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