Skip to content

Commit 267b381

Browse files
committed
change listener interfaces
1 parent f9e3358 commit 267b381

File tree

5 files changed

+113
-105
lines changed

5 files changed

+113
-105
lines changed

README.md

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ val username = "admin"
5656
val password = "secret"
5757
val rtsp = Rtsp()
5858
rtsp.init(uri, username, password)
59+
rtsp.setStatusListener(object : RtspStatusListener {
60+
override fun onConnecting() {}
61+
override fun onConnected(sdpInfo: SdpInfo) {}
62+
override fun onDisconnected() {}
63+
override fun onUnauthorized() {}
64+
override fun onFailed(message: String?) {}
65+
})
5966
rtsp.setSurfaceView(binding.svVideo)
6067
rtsp.start()
6168
// ...
@@ -68,23 +75,16 @@ rtsp.stop()
6875
e.g. for writing video stream into MP4 via muxer.
6976

7077
```kotlin
71-
val rtspStatusListener = object : RtspStatusListener {
72-
override fun onConnecting() {}
73-
override fun onConnected(sdpInfo: SdpInfo) {}
78+
// ... build rtsp
79+
rtsp.setFrameListener(object : RtspFrameListener {
7480
override fun onVideoNalUnitReceived(frame: Frame?) {
7581
// Send raw H264/H265 NAL unit to decoder
7682
}
7783
override fun onVideoFrameReceived(width: Int, height: Int, mediaImage: Image?, yuv420Bytes: ByteArray?, bitmap: Bitmap?) {}
7884
override fun onAudioSampleReceived(frame: Frame?) {
7985
// Send raw audio to decoder
8086
}
81-
override fun onDisconnected() {}
82-
override fun onUnauthorized() {}
83-
override fun onFailed(message: String?) {}
84-
}
85-
// ... build rtsp
86-
rtsp.setStatusListener(rtspStatusListener)
87-
rtsp.setSurfaceView(null) // or don't set surface view
87+
})
8888
rtsp.start(autoPlayAudio = false) // turn off autoPlayAudio
8989
// ...
9090
rtsp.stop()
@@ -95,9 +95,8 @@ rtsp.stop()
9595
### 3) You can still use library with H264/H265 to YUV MediaImage decoding
9696

9797
```kotlin
98-
val rtspStatusListener = object : RtspStatusListener {
99-
override fun onConnecting() {}
100-
override fun onConnected(sdpInfo: SdpInfo) {}
98+
// ... build rtsp
99+
rtsp.setFrameListener(object : RtspFrameListener {
101100
override fun onVideoNalUnitReceived(frame: Frame?) {}
102101
override fun onVideoFrameReceived(width: Int, height: Int, mediaImage: Image?, yuv420Bytes: ByteArray?, bitmap: Bitmap?) {
103102
if (mediaImage != null) {
@@ -112,13 +111,7 @@ val rtspStatusListener = object : RtspStatusListener {
112111
override fun onAudioSampleReceived(frame: Frame?) {
113112
// Send raw audio to decoder
114113
}
115-
override fun onDisconnected() {}
116-
override fun onUnauthorized() {}
117-
override fun onFailed(message: String?) {}
118-
}
119-
// ... build rtsp
120-
rtsp.setStatusListener(rtspStatusListener)
121-
rtsp.setSurfaceView(null) // or don't set surface view
114+
})
122115
rtsp.setRequestMediaImage(true)
123116
rtsp.start(autoPlayAudio = false) // turn off autoPlayAudio
124117
// ...
@@ -130,29 +123,22 @@ rtsp.stop()
130123
### 4) You can still use library with H264/H265 to YUV ByteArray decoding
131124

132125
```kotlin
133-
val rtspStatusListener = object : RtspStatusListener {
134-
override fun onConnecting() {}
135-
override fun onConnected(sdpInfo: SdpInfo) {}
126+
// ... build rtsp
127+
rtsp.setFrameListener(object : RtspFrameListener {
136128
override fun onVideoNalUnitReceived(frame: Frame?) {}
137129
override fun onVideoFrameReceived(width: Int, height: Int, mediaImage: Image?, yuv420Bytes: ByteArray?, bitmap: Bitmap?) {
138130
// you can decode YUV to Bitmap by Android New RenderScript Toolkit that integrated in the library
139131
// or your custom decoder
140132
/**
141133
if (yuv420Bytes != null) {
142-
Toolkit.yuvToRgbBitmap(yuv420Bytes, width, height, YuvFormat.YUV_420_888)
134+
Toolkit.yuvToRgbBitmap(yuv420Bytes, width, height, YuvFormat.YUV_420_888)
143135
}
144136
*/
145137
}
146138
override fun onAudioSampleReceived(frame: Frame?) {
147139
// Send raw audio to decoder
148140
}
149-
override fun onDisconnected() {}
150-
override fun onUnauthorized() {}
151-
override fun onFailed(message: String?) {}
152-
}
153-
// ... build rtsp
154-
rtsp.setStatusListener(rtspStatusListener)
155-
rtsp.setSurfaceView(null) // or don't set surface view
141+
})
156142
rtsp.setRequestYuvBytes(true)
157143
rtsp.start(autoPlayAudio = false) // turn off autoPlayAudio
158144
// ...
@@ -165,30 +151,23 @@ rtsp.stop()
165151
### 5) You can still use library with H264/H265 to Bitmap decoding
166152

167153
```kotlin
168-
val rtspStatusListener = object : RtspStatusListener {
169-
override fun onConnecting() {}
170-
override fun onConnected(sdpInfo: SdpInfo) {}
154+
// ... build rtsp
155+
rtsp.setFrameListener(object : RtspFrameListener {
171156
override fun onVideoNalUnitReceived(frame: Frame?) {}
172157
override fun onVideoFrameReceived(width: Int, height: Int, mediaImage: Image?, yuv420Bytes: ByteArray?, bitmap: Bitmap?) {
173158
if (bitmap != null) {
174159
// Just use it!
175160
/**
176161
binding.img.run {
177-
post { setImageBitmap(bitmap?.removeTimestamp()) }
178-
}
162+
post { setImageBitmap(bitmap?.removeTimestamp()) }
163+
}
179164
*/
180165
}
181166
}
182167
override fun onAudioSampleReceived(frame: Frame?) {
183168
// Send raw audio to decoder
184169
}
185-
override fun onDisconnected() {}
186-
override fun onUnauthorized() {}
187-
override fun onFailed(message: String?) {}
188-
}
189-
// ... build rtsp
190-
rtsp.setStatusListener(rtspStatusListener)
191-
rtsp.setSurfaceView(null) // or don't set surface view
170+
})
192171
rtsp.setRequestBitmap(true)
193172
rtsp.start(autoPlayAudio = false) // turn off autoPlayAudio
194173
// ...
@@ -215,3 +194,6 @@ launch {
215194

216195
* https://github.com/alexeyvasilyev/rtsp-client-android
217196

197+
198+
199+

app/src/main/java/ir/am3n/rtsp.client.demo/LiveFragment.kt

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import ir.am3n.rtsp.client.Rtsp
1515
import ir.am3n.rtsp.client.data.Frame
1616
import ir.am3n.rtsp.client.data.SdpInfo
1717
import ir.am3n.rtsp.client.demo.databinding.FragmentLiveBinding
18+
import ir.am3n.rtsp.client.interfaces.RtspFrameListener
1819
import ir.am3n.rtsp.client.interfaces.RtspStatusListener
1920
import kotlinx.coroutines.CoroutineScope
2021
import kotlinx.coroutines.Dispatchers
@@ -34,13 +35,14 @@ class LiveFragment : Fragment() {
3435

3536
private val rtsp = Rtsp()
3637

38+
@Volatile
39+
private var disconnectCount = 0
40+
3741
private var frameCounter = 0
3842
private var frameTimestamp = System.currentTimeMillis()
3943

40-
private val rtspStatusListener = object : RtspStatusListener {
4144

42-
@Volatile
43-
private var disconnectCount = 0
45+
private val rtspStatusListener = object : RtspStatusListener {
4446

4547
override fun onConnecting() {
4648
binding.tvFrameRate.text = ""
@@ -57,6 +59,44 @@ class LiveFragment : Fragment() {
5759
binding.pbLoading.visibility = View.GONE
5860
}
5961

62+
override fun onDisconnected() {
63+
disconnectCount++
64+
binding.tvFrameRate.text = ""
65+
binding.tvStatus.text = "RTSP disconnected"
66+
binding.bnStartStop.text = "Start RTSP"
67+
binding.pbLoading.visibility = View.GONE
68+
binding.etRtspRequest.isEnabled = true
69+
if (disconnectCount < 3) {
70+
rtsp.start()
71+
} else {
72+
val timeout = when (disconnectCount) {
73+
in 3..6 -> 1000L
74+
in 7..10 -> 3000L
75+
else -> 5000L
76+
}
77+
CoroutineScope(Dispatchers.IO).launch {
78+
delay(timeout)
79+
rtsp.start()
80+
}
81+
}
82+
}
83+
84+
override fun onUnauthorized() {
85+
binding.tvFrameRate.text = ""
86+
binding.tvStatus.text = "RTSP username or password invalid"
87+
binding.pbLoading.visibility = View.GONE
88+
}
89+
90+
override fun onFailed(message: String?) {
91+
binding.tvStatus.text = "Error: $message"
92+
binding.pbLoading.visibility = View.GONE
93+
}
94+
95+
}
96+
97+
98+
private val rtspFrameListener = object : RtspFrameListener {
99+
60100
override fun onVideoNalUnitReceived(frame: Frame?) {
61101
disconnectCount = 0
62102
frameCounter++
@@ -79,61 +119,29 @@ class LiveFragment : Fragment() {
79119
/**
80120
val task = textRecognizer.process(InputImage.fromBitmap(mediaImage, 0))
81121
val text = Tasks.await(task, 2000, TimeUnit.MILLISECONDS)
82-
*/
122+
*/
83123

84124
/**
85125
if (yuv420Bytes != null) {
86-
Toolkit.yuvToRgbBitmap(yuv420Bytes, width, height, YuvFormat.YUV_420_888)
126+
Toolkit.yuvToRgbBitmap(yuv420Bytes, width, height, YuvFormat.YUV_420_888)
87127
}
88-
*/
128+
*/
89129

90130
/**
91131
binding.img.run {
92-
post { setImageBitmap(bitmap?.removeTimestamp()) }
132+
post { setImageBitmap(bitmap?.removeTimestamp()) }
93133
}
94-
*/
134+
*/
95135

96136
}
97137

98138
override fun onAudioSampleReceived(frame: Frame?) {
99139

100140
}
101141

102-
override fun onDisconnected() {
103-
disconnectCount++
104-
binding.tvFrameRate.text = ""
105-
binding.tvStatus.text = "RTSP disconnected"
106-
binding.bnStartStop.text = "Start RTSP"
107-
binding.pbLoading.visibility = View.GONE
108-
binding.etRtspRequest.isEnabled = true
109-
if (disconnectCount < 3) {
110-
rtsp.start()
111-
} else {
112-
val timeout = when (disconnectCount) {
113-
in 3..6 -> 1000L
114-
in 7..10 -> 3000L
115-
else -> 5000L
116-
}
117-
CoroutineScope(Dispatchers.IO).launch {
118-
delay(timeout)
119-
rtsp.start()
120-
}
121-
}
122-
}
123-
124-
override fun onUnauthorized() {
125-
binding.tvFrameRate.text = ""
126-
binding.tvStatus.text = "RTSP username or password invalid"
127-
binding.pbLoading.visibility = View.GONE
128-
}
129-
130-
override fun onFailed(message: String?) {
131-
binding.tvStatus.text = "Error: $message"
132-
binding.pbLoading.visibility = View.GONE
133-
}
134-
135142
}
136143

144+
137145
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
138146
if (DEBUG) Log.v(TAG, "onCreateView()")
139147

@@ -173,6 +181,7 @@ class LiveFragment : Fragment() {
173181
}
174182

175183
rtsp.setStatusListener(rtspStatusListener)
184+
rtsp.setFrameListener(rtspFrameListener)
176185
rtsp.setSurfaceView(binding.svVideo)
177186
//rtsp.setRequestMediaImage(true)
178187
//rtsp.setRequestYuvBytes(true)

0 commit comments

Comments
 (0)