I'm trying to make a screen with a video stream from videcam in RTSP. I use MediaPlayer with SurfaceView but also I tried to use VideoView and none of that works on Android 7 (sdk 24), on other versions my code works great.
Here's the code:
class MainActivity : AppCompatActivity(), SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {
private var mediaPlayer: MediaPlayer? = null
private var vidHolder: SurfaceHolder? = null
private var vidSurface: SurfaceView? = null
private var progress: ProgressBar? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vidSurface = findViewById(R.id.videoView)
progress = findViewById(R.id.progress)
progress?.visibility = View.VISIBLE
vidHolder = vidSurface?.holder
vidHolder?.addCallback(this)
}
override fun surfaceCreated(holder: SurfaceHolder) {
try {
if (mediaPlayer != null) {
if (!mediaPlayer!!.isPlaying) mediaPlayer?.start()
} else {
mediaPlayer = MediaPlayer()
mediaPlayer?.setDataSource(CAMERA2_URL)
mediaPlayer?.setOnPreparedListener(this)
mediaPlayer?.setAudioAttributes(
AudioAttributes.Builder().setContentType(
AudioAttributes.CONTENT_TYPE_MOVIE
).build()
)
mediaPlayer?.prepareAsync()
}
mediaPlayer?.setDisplay(vidHolder)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onPrepared(mp: MediaPlayer?) {
progress?.visibility = View.GONE
mediaPlayer?.start()
}
override fun onDestroy() {
super.onDestroy()
mediaPlayer?.release()
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
override fun surfaceDestroyed(holder: SurfaceHolder) {}
}
Here's the full log when I start the app on android 7 device:
I/art: Not late-enabling -Xcheck:jni (already on)
W/art: Unexpected CPU variant for X86 using defaults: x86
W/System: ClassLoader referenced unknown path: /data/app/com.example.rtspcameratest-1/lib/x86
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
I/art: Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$2>: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/view/View$OnUnhandledKeyEventListener;
I/art: at void androidx.core.view.ViewCompat.setBackground(android.view.View, android.graphics.drawable.Drawable) (ViewCompat.java:2678)
I/art: at void androidx.appcompat.widget.ActionBarContainer.<init>(android.content.Context, android.util.AttributeSet) (ActionBarContainer.java:63)
I/art: at java.lang.Object java.lang.reflect.Constructor.newInstance0!(java.lang.Object[]) (Constructor.java:-2)
I/art: at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:430)
I/art: at android.view.View android.view.LayoutInflater.createView(java.lang.String, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:645)
I/art: at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:787)
I/art: at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet) (LayoutInflater.java:727)
I/art: at void android.view.LayoutInflater.rInflate(org.xmlpull.v1.XmlPullParser, android.view.View, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:858)
I/art: at void android.view.LayoutInflater.rInflateChildren(org.xmlpull.v1.XmlPullParser, android.view.View, android.util.AttributeSet, boolean) (LayoutInflater.java:821)
I/art: at android.view.View android.view.LayoutInflater.inflate(org.xmlpull.v1.XmlPullParser, android.view.ViewGroup, boolean) (LayoutInflater.java:518)
I/art: at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup, boolean) (LayoutInflater.java:426)
I/art: at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup) (LayoutInflater.java:377)
I/art: at android.view.ViewGroup androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor() (AppCompatDelegateImpl.java:896)
I/art: at void androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor() (AppCompatDelegateImpl.java:806)
I/art: at void androidx.appcompat.app.AppCompatDelegateImpl.setContentView(int) (AppCompatDelegateImpl.java:693)
I/art: at void androidx.appcompat.app.AppCompatActivity.setContentView(int) (AppCompatActivity.java:170)
I/art: at void com.example.rtspcameratest.MainActivity.onCreate(android.os.Bundle) (MainActivity.kt:30)
I/art: at void android.app.Activity.performCreate(android.os.Bundle) (Activity.java:6662)
I/art: at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1118)
I/art: at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2599)
I/art: at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:2707)
I/art: at void android.app.ActivityThread.-wrap12(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1)
I/art: at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1460)
I/art: at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
I/art: at void android.os.Looper.loop() (Looper.java:154)
I/art: at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6077)
I/art: at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
I/art: at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:866)
I/art: at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:756)
I/art: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.View$OnUnhandledKeyEventListener" on path: DexPathList[[zip file "/data/app/com.example.rtspcameratest-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.rtspcameratest-1/lib/x86, /system/lib, /vendor/lib]]
I/art: at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:56)
I/art: at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:380)
I/art: at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
I/art: at void androidx.core.view.ViewCompat.setBackground(android.view.View, android.graphics.drawable.Drawable) (ViewCompat.java:2678)
I/art: at void androidx.appcompat.widget.ActionBarContainer.<init>(android.content.Context, android.util.AttributeSet) (ActionBarContainer.java:63)
I/art: at java.lang.Object java.lang.reflect.Constructor.newInstance0!(java.lang.Object[]) (Constructor.java:-2)
I/art: at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:430)
I/art: at android.view.View android.view.LayoutInflater.createView(java.lang.String, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:645)
I/art: at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:787)
I/art: at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet) (LayoutInflater.java:727)
I/art: at void android.view.LayoutInflater.rInflate(org.xmlpull.v1.XmlPullParser, android.view.View, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:858)
I/art: at void android.view.LayoutInflater.rInflateChildren(org.xmlpull.v1.XmlPullParser, android.view.View, android.util.AttributeSet, boolean) (LayoutInflater.java:821)
I/art: at android.view.View android.view.LayoutInflater.inflate(org.xmlpull.v1.XmlPullParser, android.view.ViewGroup, boolean) (LayoutInflater.java:518)
I/art: at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup, boolean) (LayoutInflater.java:426)
I/art: at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup) (LayoutInflater.java:377)
I/art: at android.view.ViewGroup androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor() (AppCompatDelegateImpl.java:896)
I/art: at void androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor() (AppCompatDelegateImpl.java:806)
I/art: at void androidx.appcompat.app.AppCompatDelegateImpl.setContentView(int) (AppCompatDelegateImpl.java:693)
I/art: at void androidx.appcompat.app.AppCompatActivity.setContentView(int) (AppCompatActivity.java:170)
I/art: at void com.example.rtspcameratest.MainActivity.onCreate(android.os.Bundle) (MainActivity.kt:30)
I/art: at void android.app.Activity.performCreate(android.os.Bundle) (Activity.java:6662)
I/art: at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1118)
I/art: at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2599)
I/art: at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:2707)
I/art: at void android.app.ActivityThread.-wrap12(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1)
I/art: at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1460)
I/art: at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
I/art: at void android.os.Looper.loop() (Looper.java:154)
I/art: at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6077)
I/art: at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
I/art: at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:866)
I/art: at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:756)
W/MediaPlayer: info/warning (701, 0)
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0xa9305240: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xa9305240: ver 2 0 (tinfo 0xa9303520)
D/EGL_emulation: eglMakeCurrent: 0xa9305240: ver 2 0 (tinfo 0xa9303520)
E/MediaPlayer: error (1, -2147483648)
E/MediaPlayer: Error (1,-2147483648)
My rtsp stream config: h264 (Baseline), yuv420p(progressive), 704x576, 15 fps, 25 tbr, 90k tbn, 30 tbc
When I start it on android 7.0 it shows Error (1,-2147483648). Previously it didn't work on android 5 either, but we changed profile to Baseline and everything went fine everywhere (even on Android 7.1) except for android 7.0. I've tried some solutions from there, but nothing helped. Also I've tried to use VLC lib and that fixed android 7 problem, but it weights smth about 80 mb in apk, and that's too much for my app.
I think the problem is somwhere in stream config, but really can't figure out what exactly it could be... And that android 7 situation seems kinda strange for me because there is nothing special about the android 7 in the official info, maybe you know what it is?
So have you had any similar problem with rtsp? Do you know how to configurate rtsp stream for android in a proper way? What can be the problem with that exact Android 7 version? What can I try to make it work? Any help appreciated!
Update
I made it work by using ExoPlayer lib, but that took some time for me to do, and anyway my project gained weight (not that much as with vlc though). I still don't understand why doesn't the default Android MediaPlayer work, and if a solution appears, I will defenitely return mediaplayer code, because it's just much more simple than exoplayer.