GstLibrary改成kotlin

This commit is contained in:
Raymond Yang 2023-03-08 11:36:48 +08:00
parent 20949aa24d
commit 975e2eba79
3 changed files with 102 additions and 114 deletions

View File

@ -43,12 +43,12 @@ android {
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.7.0' implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'androidx.core:core-ktx:+' implementation 'androidx.core:core-ktx:1.9.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -1,4 +1,5 @@
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'
android { android {
ndkVersion "21.3.6528147" ndkVersion "21.3.6528147"
@ -68,6 +69,7 @@ afterEvaluate {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.core:core-ktx:1.9.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
//implementation 'androidx.appcompat:appcompat:1.6.0' //implementation 'androidx.appcompat:appcompat:1.6.0'
} }

View File

@ -1,131 +1,101 @@
package com.hisharp.gstreamer_player; package com.hisharp.gstreamer_player
import android.content.Context; import android.content.Context
import android.os.Handler; import android.util.Log
import android.os.Looper; import android.view.SurfaceHolder
import android.util.Log; import org.freedesktop.gstreamer.GStreamer
import android.view.Surface; import java.io.Closeable
import android.view.SurfaceHolder; import java.io.IOException
import android.view.SurfaceView;
import org.freedesktop.gstreamer.GStreamer; class GstLibrary(context: Context) : Closeable, SurfaceHolder.Callback {
import java.io.Closeable; private val mAppContext: Context
import java.io.IOException; private var gstCallback: GstCallback? = null
private var rtspUrl: String? = null
private var tag = ""
private var isInit = false
public class GstLibrary implements Closeable, SurfaceHolder.Callback { private external fun nativeInit() // Initialize native code, build pipeline, etc
private external fun nativeFinalize() // Destroy pipeline and shutdown native code
private external fun nativeSetUri(uri: String) // Set the URI of the media to play
private external fun nativeSetTag(tag: String) // Set the URI of the media to play
private external fun nativePlay() // Set pipeline to PLAYING
private external fun nativePause() // Set pipeline to PAUSED
private external fun nativeSurfaceInit(surface: Any) // A new surface is available
private external fun nativeSurfaceFinalize() // Surface about to be destroyed
private static final String TAG = GstLibrary.class.getSimpleName(); private val native_custom_data : Long = 0 // Native code will use this to keep private data
final Context mAppContext; fun play() {
if (!isInit) return
private GstCallback gstCallback; nativePlay()
private String rtspUrl;
private String tag = "";
private Boolean isInit = false;
public GstLibrary(Context context) {
this.mAppContext = context.getApplicationContext();
// Initialize GStreamer and warn if it fails
try {
GStreamer.init(mAppContext);
} catch (Exception e) {
new Exception("Unable initialize gstreamer.");
return;
}
nativeInit();
} }
private native void nativeInit(); // Initialize native code, build pipeline, etc fun stop() {
private native void nativeFinalize(); // Destroy pipeline and shutdown native code if (!isInit) return
private native void nativeSetUri(String uri); // Set the URI of the media to play nativePause()
private native void nativeSetTag(String tag); // Set the URI of the media to play
private native void nativePlay(); // Set pipeline to PLAYING
private native void nativePause(); // Set pipeline to PAUSED
private static native boolean nativeClassInit(); // Initialize native class: cache Method IDs for callbacks
private native void nativeSurfaceInit(Object surface); // A new surface is available
private native void nativeSurfaceFinalize(); // Surface about to be destroyed
private long native_custom_data; // Native code will use this to keep private data
//private final String defaultMediaUri = "rtsp://admin:admin@192.168.0.77:554/media/video2";
public void play() {
if (!isInit) return;
nativePlay();
} }
public void stop() { fun setRtspUrl(rtspUrl: String?) {
if (!isInit) return; this.rtspUrl = rtspUrl
nativePause();
} }
public void setRtspUrl(String rtspUrl) { fun setTag(tag: String) {
this.rtspUrl = rtspUrl; this.tag = tag
nativeSetTag(tag)
} }
public void setTag(String tag) { fun releaseSurface() {
this.tag = tag; isInit = false
nativeSetTag(tag); nativeSurfaceFinalize()
} }
public void releaseSurface() { fun setOnStatusChangeListener(callback: GstCallback?) {
isInit = false; gstCallback = callback
nativeSurfaceFinalize();
} }
public void setOnStatusChangeListener(GstCallback callback) { fun setSurfaceHolder(holder: SurfaceHolder) {
this.gstCallback = callback; holder.addCallback(this)
}
public void setSurfaceHolder(SurfaceHolder holder) {
holder.addCallback(this);
} }
// Called from native code. This sets the content of the TextView from the UI thread. // Called from native code. This sets the content of the TextView from the UI thread.
private void setMessage(final String message) { private fun setMessage(message: String) {
if (gstCallback == null) return; if (gstCallback == null) return
if (message.contains("State changed to PAUSED")) { if (message.contains("State changed to PAUSED")) {
gstCallback.onStatus(GstStatus.PAUSE); gstCallback!!.onStatus(GstStatus.PAUSE)
} else if (message.contains("State changed to PLAYING") || message.contains("Buffering complete")) { } else if (message.contains("State changed to PLAYING") || message.contains("Buffering complete")) {
gstCallback.onStatus(GstStatus.PLAYING); gstCallback!!.onStatus(GstStatus.PLAYING)
} else if (message.contains("Could not open resource for reading and writing")) { } else if (message.contains("Could not open resource for reading and writing")) {
gstCallback.onStatus(GstStatus.ERROR_WHEN_OPENING); gstCallback!!.onStatus(GstStatus.ERROR_WHEN_OPENING)
} else if (message.contains("GStreamer encountered a general supporting library error")) { } else if (message.contains("GStreamer encountered a general supporting library error")) {
gstCallback.onStatus(GstStatus.ERROR); gstCallback!!.onStatus(GstStatus.ERROR)
} else if (message.contains("Unhandled error")) { } else if (message.contains("Unhandled error")) {
gstCallback.onStatus(GstStatus.ERROR); gstCallback!!.onStatus(GstStatus.ERROR)
} else if (message.contains("Buffering")) { } else if (message.contains("Buffering")) {
gstCallback.onStatus(GstStatus.BUFFERING); gstCallback!!.onStatus(GstStatus.BUFFERING)
} }
gstCallback.onMessage(message); gstCallback!!.onMessage(message)
} }
// Called from native code. Native code calls this once it has created its pipeline and // Called from native code. Native code calls this once it has created its pipeline and
// the main loop is running, so it is ready to accept commands. // the main loop is running, so it is ready to accept commands.
private void onGStreamerInitialized () { private fun onGStreamerInitialized() {
Log.i (TAG + "+" + tag, "GStreamer initialized:"); Log.i("$TAG+$tag", "GStreamer initialized:")
if (gstCallback != null) { if (gstCallback != null) {
gstCallback.onStatus(GstStatus.READY); gstCallback!!.onStatus(GstStatus.READY)
} }
// Restore previous playing state // Restore previous playing state
if (rtspUrl != null) { if (rtspUrl != null) {
nativeSetUri(rtspUrl); nativeSetUri(rtspUrl!!)
} }
isInit = true
isInit = true;
} }
// Called from native code when the size of the media changes or is first detected. // Called from native code when the size of the media changes or is first detected.
// Inform the video surface about the new size and recalculate the layout. // Inform the video surface about the new size and recalculate the layout.
private void onMediaSizeChanged (int width, int height) { private fun onMediaSizeChanged(width: Int, height: Int) {
Log.i (TAG + "+" + tag, String.format("Media size changed to %d x %d", width, height)); Log.i("$TAG+$tag", String.format("Media size changed to %d x %d", width, height))
/*mainHandler.post(() -> { /*mainHandler.post(() -> {
surfaceView.media_width = width; surfaceView.media_width = width;
surfaceView.media_height = height; surfaceView.media_height = height;
@ -133,40 +103,56 @@ public class GstLibrary implements Closeable, SurfaceHolder.Callback {
});*/ });*/
} }
static { init {
System.loadLibrary("gstreamer_android"); mAppContext = context.applicationContext
System.loadLibrary("gst_player");
nativeClassInit(); // Initialize GStreamer and warn if it fails
try {
GStreamer.init(mAppContext)
} catch (e: Exception) {
Exception("Unable initialize gstreamer.")
}
nativeInit()
} }
@Override @Throws(IOException::class)
public void close() throws IOException { override fun close() {
isInit = false; isInit = false
try { try {
nativeFinalize(); nativeFinalize()
} catch (Exception e) { } catch (e: Exception) {
e.printStackTrace(); e.printStackTrace()
} }
} }
@Override override fun surfaceCreated(holder: SurfaceHolder) {
public void surfaceCreated(SurfaceHolder holder) { Log.d("$TAG+$tag", "Surface created: " + holder.surface)
Log.d(TAG + "+" + tag, "Surface created: " + holder.getSurface()); Log.i("$TAG+$tag", "GStreamer surfaceCreated")
Log.i (TAG + "+" + tag, "GStreamer surfaceCreated"); isInit = true
isInit = true; nativeSurfaceInit(holder.surface)
nativeSurfaceInit(holder.getSurface());
} }
@Override override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d("$TAG+$tag", String.format("Surface changed, format: %d, width: %d, height: %d", format, width, height))
Log.d(TAG + "+" + tag, String.format("Surface changed, format: %d, width: %d, height: %d", format, width, height));
/*setSurfaceHolder(holder);*/ /*setSurfaceHolder(holder);*/
} }
@Override override fun surfaceDestroyed(holder: SurfaceHolder) {
public void surfaceDestroyed(SurfaceHolder holder) { Log.d("$TAG+$tag", "Surface destroyed")
Log.d(TAG + "+" + tag, "Surface destroyed"); releaseSurface()
releaseSurface(); isInit = false
isInit = false;
} }
}
companion object {
private val TAG = GstLibrary::class.java.simpleName
@JvmStatic
private external fun nativeClassInit(): Boolean // Initialize native class: cache Method IDs for callbacks
init {
System.loadLibrary("gstreamer_android")
System.loadLibrary("gst_player")
nativeClassInit()
}
}
}