Hi,
I am trying to display a MJPEG stream on my Android phone using the MJPEG B4J example. I have adapted this example to B4A and my needs, just one stream. The stream displays perfectly in a web browser, but I don't get it running on my phone. The connection is made, but no image is shown.
My code at this moment is for Main :
and for MJPEG:
Does somebody have a complete example how to realize what I want or can point to errors are have made.
Harry
I am trying to display a MJPEG stream on my Android phone using the MJPEG B4J example. I have adapted this example to B4A and my needs, just one stream. The stream displays perfectly in a web browser, but I don't get it running on my phone. The connection is made, but no image is shown.
My code at this moment is for Main :
B4X:
#Region Project Attributes
#ApplicationLabel: B4A Example
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Private mj1 As MJPEG
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Private ImageView1 As ImageView
End Sub
Sub Activity_Create(FirstTime As Boolean)
'Do not forget to load the layout file created with the visual designer. For example:
'Activity.LoadLayout("Layout1")
Activity.LoadLayout("1")
mj1.Initialize(Me, "mj1")
mj1.Connect("192.168.2.4/",8000)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub mj1_Frame(bmp As Bitmap)
ImageView1.SetBackgroundImage(bmp)
End Sub
and for MJPEG:
B4X:
Sub Class_Globals
Private sock As Socket
Private Astream As AsyncStreams
Private mCallback As Object
Private mEventName As String
Private mHost As String
Private mPath As String
Private Data(1000000) As Byte
Private index As Int
Private bc As ByteConverter
Private boundary As String
End Sub
Public Sub Initialize (Callback As Object, EventName As String)
mCallback = Callback
mEventName = EventName
End Sub
Public Sub Connect(url As String, Port As Int)
If Astream.IsInitialized Then Astream.Close
Dim i As Int = url.IndexOf("/")
mPath = url.SubString(i)
mHost = url.SubString2(0, i)
sock.Initialize("sock")
Log(mHost)
Log(Port)
sock.Connect(mHost, Port, 30000)
End Sub
Private Sub Sock_Connected (Successful As Boolean)
If Successful Then
Log("connected")
boundary = ""
Astream.Initialize(sock.InputStream, sock.OutputStream, "astream")
Dim sTmp As String = $"GET ${mPath} HTTP/1.1
Host: ${mHost}
Connection: keep-alive
"$
Astream.Write(sTmp.Replace(Chr(10), CRLF).GetBytes("UTF8"))
End If
End Sub
Private Sub AStream_NewData (Buffer() As Byte)
'Log(Buffer)
bc.ArrayCopy(Buffer, 0, Data, index, Buffer.Length)
index = index + Buffer.Length
If boundary = "" Then
Dim i1 As Int = IndexOfString("Content-Type", 0)
If i1 > -1 Then
Dim i2 As Int = IndexOfString(CRLF, i1 + 1)
If i2 > -1 Then
Dim ct As String = BytesToString(Data, i1, i2 - i1, "ASCII")
Dim b As Int = ct.IndexOf("=")
boundary = ct.SubString(b + 1)
End If
End If
Else
Dim b1 As Int = IndexOfString(boundary, 0)
If b1 > -1 Then
Dim b2 As Int = IndexOfString(boundary, b1 + 1)
If b2 > -1 Then
Dim startframe As Int = IndexOf(Array As Byte(0xff, 0xd8), b1)
Dim endframe As Int = IndexOf(Array As Byte(0xff, 0xd9), b2 - 10)
If startframe > -1 And endframe > -1 Then
Dim In As InputStream
In.InitializeFromBytesArray(Data, startframe, endframe - startframe + 2)
#if B4J
Dim bmp As Image
#else
Dim bmp As Bitmap
#end if
bmp.Initialize2(In)
CallSub2(mCallback, mEventName & "_frame", bmp)
End If
TrimArray(b2)
End If
End If
End If
End Sub
Private Sub TrimArray (i As Int)
bc.ArrayCopy(Data, i, Data, 0, index - i)
index = index - i
End Sub
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
End If
Next
If b = bs.Length Then
Return i
End If
Next
Return -1
End Sub
Private Sub AStream_Error
Log("error")
End Sub
Private Sub Astream_Terminated
Log("Terminated")
End Sub
Does somebody have a complete example how to realize what I want or can point to errors are have made.
Harry