Closed kishorpise closed 3 weeks ago
Hello,
Did you add jitpack maven repository to your project?
Yes, I have added - here is my setting.
Then I downloaded code and compiled to produce the aar files at my end. I copied these files to lib folder-
Then I added libraries like this -
I am not sure on how to get the Connection Checker object.
Looks like some thing is wrong.
Hello,
ConnectChecker is an interface that provide you stream events.
You have examples in the app of the repository
Correct, I can see the interface in source code, but its not getting exposed, here is snapshot from the android studio.
I just want to play rtsp stream from camera. is any library missing or some name spaces are wrongly placed. my code is java and library is in Kotlin. not sure how to resolve.
Hello,
I think that you should focus on resolve the problem compiling with cradle instead of compile .aar directly. Can you show me all your grade files using the lines recommended in the readme?
My entire gradle file is below.
`plugins { id 'com.android.application' }
android { namespace 'com.test' compileSdk 34
defaultConfig {
applicationId "com.test"
minSdk 22
targetSdk 34
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies { implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'com.google.android.material:material:1.12.0' implementation fileTree(dir: 'libs', include: ['.aar', '.jar'], exclude: [])
}`
I have used approach to compile and put .aar files as com.github.pedro***** is not searchable or found online. please refer first screen shot of this issue.
Hello,
I checked the gradle url and it is available online so I think that the problem is related with your config. Did you tried with the last Android studio version and a clean app?
Finally I am able to compile as below. I downloaded new android studio. Created fresh new project. and below is code.. which is crashing -
`<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rlContainer" android:layout_width="match_parent" android:layout_height="match_parent">
<com.pedro.library.view.OpenGlView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.pedro.library.view.OpenGlView>
`
and in code
private RtspCamera1 rtspCamera1; private OpenGlView openGlView;
Here is method
` private void LoadCamera() {
rtspCamera1 = new RtspCamera1(openGlView, new ConnectCheckerEvent() {
@Override
public void onStreamEvent(StreamEvent event, String message) {
}
});
rtspCamera1.prepareVideo(); rtspCamera1.startStream("rtsp://10.0.0.134:554/11");
}`
This device is api level 19 - old. Any help or guidance is appreciated. Error is - Caused by: java.lang.NullPointerException: getSurfaceTexture(...) must not be null
Hello,
You need wait until the OpenGlView is ready before call startStream:
openGlView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//openGlView is ready, you can call, startPreview, startStream or startRecord now
if (rtspCamera1.prepareVideo() && rtspCamera1.prepareAudio()) {
rtspCamera1.startStream("rtsp://10.0.0.134:554/11");
}
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
Here is my error ... Fail to connect to camera service.
My entire class is here. I guess I need to write some service class as given in example. however its in kotlin. is there any java version ?
I am also looking for authentication method as not all cameras have direct access they have user and pass. Once This is running, I will share entire code on GH for some one to refer as java sample.
` private void LoadCamera() {
rtspCamera1 = new RtspCamera1(openGlView, new ConnectCheckerEvent() {
@Override
public void onStreamEvent(StreamEvent event, String message) {
if (event ==StreamEvent.CONNECTED){
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event ==StreamEvent.DISCONNECTED){
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event ==StreamEvent.AUTH_ERROR){
Toast.makeText(MainActivity.this, "DISCONNECTED ", Toast.LENGTH_SHORT).show();
}
if (event ==StreamEvent.AUTH_SUCCESS){
Toast.makeText(MainActivity.this, "AUTH_SUCCESS ", Toast.LENGTH_SHORT).show();
}
if (event ==StreamEvent.FAILED){
Toast.makeText(MainActivity.this, "FAILED ", Toast.LENGTH_SHORT).show();
}
if (event ==StreamEvent.STARTED){
Toast.makeText(MainActivity.this, "STARTED ", Toast.LENGTH_SHORT).show();
}
}
});
rtspCamera1.prepareVideo();
openGlView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//openGlView is ready, you can call, startPreview, startStream or startRecord now
if (rtspCamera1.prepareVideo() && rtspCamera1.prepareAudio()) {
rtspCamera1.startStream("rtsp://10.0.0.134:554/11");
}
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
}
`
Fail to connect to camera service
You need request and accept camera and microphone permissions before use the library.
I made code modifications as below.
1) Device API 19. Permissions are not required. So code modified as -
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { checkPermissions(); } else { LoadCamera(); }
and the entire code as below -
` private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE);
} else {
LoadCamera();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode
== PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
LoadCamera();
} else {
Toast.makeText(this, "Camera and microphone permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
private void LoadCamera() {
rtspCamera1 = new RtspCamera1(openGlView, new ConnectCheckerEvent() {
@Override
public void onStreamEvent(StreamEvent event, String message) {
if (event == StreamEvent.CONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.DISCONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_ERROR) {
Toast.makeText(MainActivity.this, "DISCONNECTED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_SUCCESS) {
Toast.makeText(MainActivity.this, "AUTH_SUCCESS ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.FAILED) {
Toast.makeText(MainActivity.this, "FAILED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.STARTED) {
Toast.makeText(MainActivity.this, "STARTED ", Toast.LENGTH_SHORT).show();
}
}
});
rtspCamera1.prepareVideo();
openGlView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//openGlView is ready, you can call, startPreview, startStream or startRecord now
if (rtspCamera1.prepareVideo() && rtspCamera1.prepareAudio()) {
rtspCamera1.startStream("rtsp://10.0.0.134:554/11");
// rtspCamera1.startStream("rtsp://10.0.0.245:1935/");
}
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
}`
log cat - Below errors reported -
Could not find method com.viewer.MainActivity.requestPermissions, referenced from method com.viewer.MainActivity.checkPermissions
Could not find method androidx.core.app.ComponentActivity.onMultiWindowModeChanged, referenced from method androidx.activity.ComponentActivity.onMultiWindowModeChanged
Looks like there is some issue with the androidx. This sample project is api 19 and looks like you have some references in library for androidx. Will do research tomorrow as this is late.
You don't need request permissions until API 23+ but you still need declare permissions in the manifest. About the not found error, you need make sure that you have androidx dependencies declared (In this case appcompact library) and make your activity extends from AppCompactActivity instead of Activity.
Unfortunately, It does not work.
Here is manifest.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-sdk android:minSdkVersion="19" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
Here is code after change -
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.activity.ComponentActivity;
import com.pedro.common.ConnectCheckerEvent;
import com.pedro.common.StreamEvent;
import com.pedro.library.rtsp.RtspCamera1;
import com.pedro.library.view.OpenGlView;
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 100;
private RtspCamera1 rtspCamera1;
private OpenGlView openGlView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
openGlView = findViewById(R.id.surfaceView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkPermissions();
} else {
LoadCamera();
}
}
private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE);
} else {
LoadCamera();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode
== PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
LoadCamera();
} else {
Toast.makeText(this, "Camera and microphone permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
private void LoadCamera() {
rtspCamera1 = new RtspCamera1(openGlView, new ConnectCheckerEvent() {
@Override
public void onStreamEvent(StreamEvent event, String message) {
if (event == StreamEvent.CONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.DISCONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_ERROR) {
Toast.makeText(MainActivity.this, "DISCONNECTED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_SUCCESS) {
Toast.makeText(MainActivity.this, "AUTH_SUCCESS ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.FAILED) {
Toast.makeText(MainActivity.this, "FAILED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.STARTED) {
Toast.makeText(MainActivity.this, "STARTED ", Toast.LENGTH_SHORT).show();
}
}
});
rtspCamera1.prepareVideo();
openGlView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//openGlView is ready, you can call, startPreview, startStream or startRecord now
if (rtspCamera1.prepareVideo() && rtspCamera1.prepareAudio()) {
// rtspCamera1.startStream("rtsp://10.0.0.134:554/11");
rtspCamera1.startStream("rtsp://10.0.0.245:1935/");
}
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
}
}
Your code fixed to works. The problem was that you declare the openglview callbacks after that the event is called, you should declare it in the onCreate method to handle it correctly:
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 100;
private RtspCamera1 rtspCamera1;
private OpenGlView openGlView;
private final String[] permissions = new String[] {
Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
openGlView = findViewById(R.id.surfaceView);
loadCamera();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
startStream();
} else {
Toast.makeText(this, "Camera and microphone permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
private void startStream() {
if (rtspCamera1.prepareVideo() && rtspCamera1.prepareAudio()) {
rtspCamera1.startStream("rtsp://10.0.0.245:1935/");
}
}
private void loadCamera() {
rtspCamera1 = new RtspCamera1(openGlView, new ConnectCheckerEvent() {
@Override
public void onStreamEvent(StreamEvent event, String message) {
if (event == StreamEvent.CONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.DISCONNECTED) {
Toast.makeText(MainActivity.this, "Connected ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_ERROR) {
Toast.makeText(MainActivity.this, "DISCONNECTED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.AUTH_SUCCESS) {
Toast.makeText(MainActivity.this, "AUTH_SUCCESS ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.FAILED) {
Toast.makeText(MainActivity.this, "FAILED ", Toast.LENGTH_SHORT).show();
}
if (event == StreamEvent.STARTED) {
Toast.makeText(MainActivity.this, "STARTED ", Toast.LENGTH_SHORT).show();
}
}
});
openGlView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//openGlView is ready, you can call, startPreview, startStream or startRecord now
ActivityCompat.requestPermissions(MainActivity.this, permissions, PERMISSION_REQUEST_CODE);
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
}
}
This code is not ideal because you are not closing the camera or handle the activity lifecycle correctly. Please check this code to know how to do it correctly. The only difference is that this class use a TextureView to suport device with API 16+. You can continue using OpenGlView: https://github.com/pedroSG94/RootEncoder/blob/master/app/src/main/java/com/pedro/streamer/oldapi/OldApiActivity.kt
This issue will be moved to discussion tomorrow because it is only a question
I have copied exact code provided as above. Still does not work, but now application does not crash. It shows local camera instead of remote camera. Tested multiple camera address.
Error reported - Error configure stream, announce failed
Here is truncated logcat - output
`VideoEncoder com.viewer I prepared MicrophoneManager com.viewer I Microphone created, 32000hz, Stereo 2024-09-17 16:57:48.823 29704-29704 AudioEncoder com.viewer I 2 encoders found 2024-09-17 16:57:48.824 29704-29704 AudioEncoder com.viewer I Encoder selected c2.android.aac.encoder SurfaceManager com.viewer E GL already released
libc com.viewer W Access denied finding property "vendor.mali.platform.config" 2024-09-17 16:57:48.958 29704-29849 libc com.viewer W Access denied finding property "vendor.mali.debug.config" SurfaceManager com.viewer E GL already released CommandsManager com.viewer I OPTIONS rtsp://10.0.0.134:554/11 RTSP/1.0
CommandsManager com.viewer I RTSP/1.0 200 OK CSeq: 1 Server: Hipcam RealServer/V1.0 Public: OPTIONS,DESCRIBE,SETUP,TEARDOWN,PLAY,SET_PARAMETER,GET_PARAMETER 2024-09-17 16:57:49.995 29704-29893 CommandsManager com.viewer I ANNOUNCE rtsp://10.0.0.134:554/11 RTSP/1.0 Content-Type: application/sdp CSeq: 2 Content-Length: 447
v=0
o=- 0 0 IN IP4 127.0.0.1
s=Unnamed
i=N/A
c=IN IP4 10.0.0.134
t=0 0
a=recvonly
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0LAH42NUFAek1BgEGQAAAMABAAAAwDyPCIRqA==,aM48gA==
a=control:streamid=0
m=audio 0 RTP/AVP 97
a=rtpmap:97 MPEG4-GENERIC/32000/2
a=fmtp:97 profile-level-id=1; mode=AAC-hbr; config=1290; sizelength=13; indexlength=3; indexdeltalength=3
a=control:streamid=1
2024-09-17 16:57:50.093 29704-29893 CommandsManager com.viewer I RTSP/1.0 400 Bad Request CSeq: 1 Server: Hipcam RealServer/V1.0
`
Hello,
Yes, that is the expected.
This library is used to send video/audio to a media server as you can see in the readme. Not to receive data from an IP camera.
If you want to reproduce an IP camera try with VLC or exoplayer
Hello, Please see the below error.
and
Let me know how can I resolve this issue ? instead of compiling