If you need to obtain raw frames (e.g., for writing to an MP4 via a muxer) without using the built-in UI components, use the RtspClient API. You must implement RtspClient.RtspClientListener to handle incoming NAL units, audio samples, or application data.
Implementation Example
val rtspClientListener = object: RtspClient.RtspClientListener {
override fun onRtspConnecting() {}
override fun onRtspConnected(sdpInfo: SdpInfo) {}
override fun onRtspVideoNalUnitReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw H264/H265 NAL unit to decoder
}
override fun onRtspAudioSampleReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw audio to decoder
}
override fun onRtspApplicationDataReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw application data to app specific parser
}
override fun onRtspDisconnected() {}
override fun onRtspFailedUnauthorized() {
Log.e(TAG, "RTSP failed unauthorized")
}
override fun onRtspFailed(message: String?) {
Log.e(TAG, "RTSP failed with message '$message'")
}
}
val uri = Uri.parse("rtsps://10.0.1.3/test.sdp")
val username = "admin"
val password = "secret"
val stopped = new AtomicBoolean(false)
// Create a socket (e.g., via NetUtils for SSL/TLS)
val sslSocket = NetUtils.createSslSocketAndConnect(uri.getHost(), uri.getPort(), 5000)
val rtspClient = RtspClient.Builder(sslSocket, uri.toString(), stopped, rtspClientListener)
.requestVideo(true)
.requestAudio(true)
.withDebug(false)
.withUserAgent("RTSP client")
.withCredentials(username, password)
.build()
// Blocking call until 'stopped' becomes true or connection fails
rtspClient.execute()
NetUtils.closeSocket(sslSocket)
val rtspClientListener = object: RtspClient.RtspClientListener {
override fun onRtspConnecting() {}
override fun onRtspConnected(sdpInfo: SdpInfo) {}
override fun onRtspVideoNalUnitReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw H264/H265 NAL unit to decoder
}
override fun onRtspAudioSampleReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw audio to decoder
}
override fun onRtspApplicationDataReceived(data: ByteArray, offset: Int, length: Int, timestamp: Long) {
// Send raw application data to app specific parser
}
override fun onRtspDisconnected() {}
override fun onRtspFailedUnauthorized() {
Log.e(TAG, "RTSP failed unauthorized");
}
override fun onRtspFailed(message: String?) {
Log.e(TAG, "RTSP failed with message '$message'")
}
}
val uri = Uri.parse("rtsps://10.0.1.3/test.sdp")
val username = "admin"
val password = "secret"
val stopped = new AtomicBoolean(false)
val sslSocket = NetUtils.createSslSocketAndConnect(uri.getHost(), uri.getPort(), 5000)
val rtspClient = RtspClient.Builder(sslSocket, uri.toString(), stopped, rtspClientListener)
.requestVideo(true)
.requestAudio(true)
.withDebug(false)
.withUserAgent("RTSP client")
.withCredentials(username, password)
.build()
// Blocking call until stopped variable is true or connection failed
rtspClient.execute()
NetUtils.closeSocket(sslSocket)