2 * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.samsung.android.modules.rtsp;
18 import android.net.Uri;
19 import android.util.Log;
21 import androidx.annotation.NonNull;
23 import com.alexvas.rtsp.RtspClient;
24 import com.alexvas.utils.NetUtils;
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
29 import java.net.Socket;
30 import java.util.concurrent.atomic.AtomicBoolean;
33 * RTSPClient class to implement RTSP client side functionalities
35 public class RTSPClient {
36 private static final String TAG = "RTSPClient";
37 private static volatile Socket clientSocket;
38 private static final int sdpInfoSize = 30;
39 private static final int socketTimeout = 10000;
40 private String rtspUrl = null;
43 private final AtomicBoolean exitFlag;
44 private final ReceiveDataCallback streamCb;
45 private RtspClient mRtspClient;
46 private H264Decoder decoder;
51 * Interface to implement DataCallback from RTSP module to RTSP stream
53 public interface ReceiveDataCallback {
54 void pushData(byte[] frame);
58 * Interface to implement socket connection callback
60 public interface SocketConnectCallback {
61 void socketConnect(Boolean bool);
65 * RTSPClient class constructor
66 * @param exitFlag AtomicBoolean flag to exit execution
67 * @param cb callback object to send data to upper layer
69 public RTSPClient(AtomicBoolean exitFlag, ReceiveDataCallback cb) {
70 this.exitFlag = exitFlag;
75 * Method to create a client socket for RTSP connection with RTSP server
76 * @param socketCB socket connection callback to notify success/failure of socket creation
78 public void createClientSocket(SocketConnectCallback socketCB){
79 if (rtspUrl == null || rtspUrl.isEmpty()) {
80 Log.e(TAG, "Failed create client socket: Invalid RTSP URL");
84 Uri uri = Uri.parse(rtspUrl);
86 Thread thread = new Thread(() -> {
88 clientSocket = NetUtils.createSocketAndConnect(uri.getHost(), uri.getPort(), socketTimeout);
89 if(clientSocket != null)
90 socketCB.socketConnect(true);
91 } catch (Exception e) {
92 socketCB.socketConnect(false);
93 Log.d(TAG, "Exception in RTSP client socket creation");
99 } catch (Exception e) {
100 Log.e(TAG, "Exception in RTSP client socket creation");
105 * Method to create RtspClient object to access RTSP lib from dependency
107 public void initRtspClient() {
109 RtspClient.RtspClientListener clientListener = new RtspClient.RtspClientListener() {
111 public void onRtspConnecting() {
112 Log.d(TAG, "Connecting to RTSP server");
116 public void onRtspConnected(@NonNull @NotNull RtspClient.SdpInfo sdpInfo) {
117 Log.d(TAG, "Connected to RTSP server");
118 if(sdpInfo.videoTrack != null) {
119 sps = sdpInfo.videoTrack.sps;
120 pps = sdpInfo.videoTrack.pps;
125 public void onRtspVideoNalUnitReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
126 Log.d(TAG, "RTSP video stream callback -- video NAL units received");
127 if (bytes.length < sdpInfoSize)
128 decoder.initH264Decoder(sps, pps);
130 decoder.setRawH264Data(bytes);
134 public void onRtspAudioSampleReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
135 //TODO : Decode the Audio Nal units (AAC encoded) received using audio decoder
136 Log.d(TAG, "RTSP audio stream callback");
140 public void onRtspDisconnected() {
141 decoder.stopDecoder();
142 Log.d(TAG, "Disconnected from RTSP server");
146 public void onRtspFailedUnauthorized() {
147 Log.d(TAG, "onRtspFailedUnauthorized");
151 public void onRtspFailed(@androidx.annotation.Nullable @Nullable String s) {
152 Log.d(TAG, "onRtspFailed");
156 Uri uri = Uri.parse(rtspUrl);
158 decoder = new H264Decoder(streamCb, height, width);
159 mRtspClient = new RtspClient.Builder(clientSocket, uri.toString(), exitFlag, clientListener)
163 .withUserAgent("RTSP sample Client")
168 * Method to start RTSP streaming
170 public void start() {
171 mRtspClient.execute();
175 * Method to stop RTSP streaming
179 NetUtils.closeSocket(clientSocket);
180 decoder.stopDecoder();
181 } catch (Exception E) {
182 Log.e(TAG, "Error closing socket");
187 * Method to set RTSP URL
188 * @param url String for RTSP URL
190 public void setRtspUrl(String url) {
195 * Method to set RTSP frame resolution
196 * @param height Height of the RTSP stream
197 * @param width Width of the RTSP stream
199 public void setResolution(int height, int width) {
200 this.height = height;