初步避開閃退問題

This commit is contained in:
Raymond Yang 2023-01-19 16:07:10 +08:00
parent e48ebcbb02
commit eb4f643e99
6 changed files with 74 additions and 37 deletions

View File

@ -84,6 +84,7 @@ class MainActivity : AppCompatActivity() {
viewModel.cameraList.observe(this) { list ->
this.videos = list
reloadVideoViews(this.videos)
currentPage = 0
}
}

View File

@ -1,6 +1,9 @@
package com.ray650128.gstreamer_demo_app
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
@ -8,7 +11,6 @@ import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import com.hisharp.gstreamer_player.GStreamerSurfaceView
import com.hisharp.gstreamer_player.GstCallback
import com.hisharp.gstreamer_player.GstLibrary
import com.hisharp.gstreamer_player.GstStatus
@ -53,12 +55,18 @@ class VideoView : ConstraintLayout, SurfaceHolder.Callback, GstCallback {
private var retryCount = 0
private val mHandler: MyHandler by lazy {
MyHandler(Looper.getMainLooper())
}
private fun initView(context: Context) {
val layoutInflater = LayoutInflater.from(context)
view = ItemVideoViewBinding.inflate(layoutInflater, this, true)
view.baseView.clipToOutline = true
videoView.holder.addCallback(this)
gstLibrary = GstLibrary(context)
gstLibrary.setOnStatusChangeListener(this)
}
fun setData(device: Device?) {
@ -70,7 +78,8 @@ class VideoView : ConstraintLayout, SurfaceHolder.Callback, GstCallback {
this.tag = device.name
view.textDeviceName.text = device.name
view.textDeviceName.isVisible = true
Log.d(TAG, "Set device to: $device")
gstLibrary.setRtspUrl(this.data?.rtspUrl)
Log.d("${TAG}_$tag", "Set device to: $device")
}
fun setTextVisible(isVisible: Boolean) {
@ -83,59 +92,79 @@ class VideoView : ConstraintLayout, SurfaceHolder.Callback, GstCallback {
}
fun play() {
videoView.isVisible = true
gstLibrary = GstLibrary(context)
gstLibrary.setRtspUrl(this.data?.rtspUrl)
gstLibrary.setOnStatusChangeListener(this)
//videoView.isVisible = true
videoView.postInvalidate()
gstLibrary.play()
retryCount = 0
}
fun stop() {
videoView.isVisible = false
//videoView.isVisible = false
isPlaying = false
if (this::gstLibrary.isInitialized) {
gstLibrary.stop()
gstLibrary.setOnStatusChangeListener(null)
//gstLibrary.releaseSurface()
}
retryCount = 999
}
override fun surfaceCreated(holder: SurfaceHolder) {
Log.d(TAG, "Surface created: " + holder.surface)
Log.d("${TAG}_$tag", "Surface created: " + holder.surface)
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
Log.d(TAG, "Surface changed to format: $format, width: $width, height: $height")
Log.d("${TAG}_$tag", "Surface changed to format: $format, width: $width, height: $height")
if (this::gstLibrary.isInitialized) {
gstLibrary.setSurfaceHolder(holder)
}
}
override fun surfaceDestroyed(p0: SurfaceHolder) {
Log.d(TAG, "Surface destroyed")
if (this::gstLibrary.isInitialized) {
//gstLibrary.releaseSurface()
}
Log.d("${TAG}_$tag", "Surface destroyed")
/*if (this::gstLibrary.isInitialized) {
gstLibrary.releaseSurface()
}*/
}
override fun onStatus(gstInstance: GstLibrary?, gstStatus: GstStatus?) {
override fun onStatus(gstStatus: GstStatus?) {
when (gstStatus) {
GstStatus.PLAYING -> {
isLoading = false
isPlaying = true
mHandler.sendMessage(
Message().apply {
what = MSG_PLAY
}
)
}
GstStatus.PAUSE -> {
isPlaying = false
isLoading = false
mHandler.sendMessage(
Message().apply {
what = MSG_PAUSE
}
)
}
else -> {}
}
Log.e(TAG, "onStatus: $gstStatus")
Log.e("${TAG}_$tag", "onStatus: $gstStatus")
}
override fun onMessage(gstInstance: GstLibrary?, message: String?) {
gstLibrary.play()
Log.e(TAG, "onMessage: $message")
override fun onMessage(message: String?) {
Log.e("${TAG}_$tag", "onMessage: $message")
}
inner class MyHandler(looper: Looper): Handler(looper) {
override fun handleMessage(msg: Message) {
//super.handleMessage(msg)
when(msg.what) {
MSG_PAUSE -> {
isPlaying = false
isLoading = false
}
MSG_PLAY -> {
isLoading = false
isPlaying = true
}
}
}
}
companion object {
@ -143,5 +172,9 @@ class VideoView : ConstraintLayout, SurfaceHolder.Callback, GstCallback {
const val MAIN_STREAM = 1
const val SUB_STREAM = 2
private const val MSG_PAUSE = 1
private const val MSG_PLAY = 2
}
}

View File

@ -21,6 +21,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -348,8 +348,8 @@ void gst_native_set_uri(JNIEnv *env, jobject thiz, jstring uri) {
gst_element_set_state(data->pipeline, GST_STATE_READY);
g_object_set(data->pipeline, "uri", char_uri, NULL);
(*env)->ReleaseStringUTFChars(env, uri, char_uri);
data->is_live |=
(gst_element_set_state(data->pipeline, data->target_state) == GST_STATE_CHANGE_NO_PREROLL);
g_object_set(data->pipeline, "latency", 250, NULL);
data->is_live = (gst_element_set_state(data->pipeline, data->target_state) == GST_STATE_CHANGE_NO_PREROLL);
}
/* Set pipeline to PLAYING state */
@ -359,7 +359,7 @@ static void gst_native_play(JNIEnv *env, jobject thiz) {
return;
GST_DEBUG ("Setting state to PLAYING");
data->target_state = GST_STATE_PLAYING;
data->is_live |= (gst_element_set_state(data->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_NO_PREROLL);
data->is_live = (gst_element_set_state(data->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_NO_PREROLL);
}
/* Set pipeline to PAUSED state */
@ -369,7 +369,7 @@ static void gst_native_pause(JNIEnv *env, jobject thiz) {
return;
GST_DEBUG ("Setting state to PAUSED");
data->target_state = GST_STATE_PAUSED;
data->is_live |=(gst_element_set_state(data->pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_NO_PREROLL);
data->is_live = (gst_element_set_state(data->pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_NO_PREROLL);
}
/* Static class initializer: retrieve method and field IDs */

View File

@ -1,6 +1,6 @@
package com.hisharp.gstreamer_player;
public interface GstCallback {
void onStatus(GstLibrary gstInstance, GstStatus gstStatus);
void onMessage(GstLibrary gstInstance, String message);
void onStatus(GstStatus gstStatus);
void onMessage(String message);
}

View File

@ -75,17 +75,17 @@ public class GstLibrary implements Closeable {
private void setMessage(final String message) {
if (gstCallback == null) return;
if (message.contains("State changed to PAUSED")) {
gstCallback.onStatus(this, GstStatus.PAUSE);
gstCallback.onStatus(GstStatus.PAUSE);
} else if (message.contains("State changed to PLAYING")) {
gstCallback.onStatus(this, GstStatus.PLAYING);
gstCallback.onStatus(GstStatus.PLAYING);
} else if (message.contains("Could not open resource for reading and writing")) {
gstCallback.onStatus(this, GstStatus.ERROR_WHEN_OPENING);
gstCallback.onStatus(GstStatus.ERROR_WHEN_OPENING);
} else if (message.contains("GStreamer encountered a general supporting library error")) {
gstCallback.onStatus(this, GstStatus.ERROR);
gstCallback.onStatus(GstStatus.ERROR);
} else if (message.contains("Unhandled error")) {
gstCallback.onStatus(this, GstStatus.ERROR);
gstCallback.onStatus(GstStatus.ERROR);
}
gstCallback.onMessage(this, message);
gstCallback.onMessage(message);
}
// Called from native code. Native code calls this once it has created its pipeline and
@ -94,11 +94,13 @@ public class GstLibrary implements Closeable {
Log.i ("GStreamer", "GStreamer initialized:");
if (gstCallback != null) {
gstCallback.onStatus(this, GstStatus.READY);
gstCallback.onStatus(GstStatus.READY);
}
// Restore previous playing state
nativeSetUri (rtspUrl);
if (rtspUrl != null) {
nativeSetUri(rtspUrl);
}
}
// Called from native code when the size of the media changes or is first detected.