Add support for selecting files

This commit is contained in:
Sebastian Dröge 2012-10-02 13:31:39 +02:00
parent 3111a6f6e2
commit e3b897f4b5
4 changed files with 58 additions and 14 deletions

View file

@ -345,8 +345,11 @@ void gst_native_set_uri (JNIEnv* env, jobject thiz, jstring uri) {
if (!data) return; if (!data) return;
const jbyte *char_uri = (*env)->GetStringUTFChars (env, uri, NULL); const jbyte *char_uri = (*env)->GetStringUTFChars (env, uri, NULL);
GST_DEBUG ("Setting URI to %s", char_uri); GST_DEBUG ("Setting URI to %s", char_uri);
if (data->target_state >= GST_STATE_READY)
gst_element_set_state (data->pipeline, GST_STATE_READY);
g_object_set(data->pipeline, "uri", char_uri); g_object_set(data->pipeline, "uri", char_uri);
(*env)->ReleaseStringUTFChars (env, uri, char_uri); (*env)->ReleaseStringUTFChars (env, uri, char_uri);
data->is_live = (gst_element_set_state (data->pipeline, data->target_state) == GST_STATE_CHANGE_NO_PREROLL);
} }
void gst_native_play (JNIEnv* env, jobject thiz) { void gst_native_play (JNIEnv* env, jobject thiz) {

View file

@ -30,6 +30,14 @@
android:src="@android:drawable/ic_media_pause" android:src="@android:drawable/ic_media_pause"
android:text="@string/button_stop" /> android:text="@string/button_stop" />
<ImageButton
android:id="@+id/button_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/button_select"
android:src="@android:drawable/ic_media_next"
android:text="@string/button_select" />
<TextView <TextView
android:id="@+id/textview_time" android:id="@+id/textview_time"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View file

@ -3,4 +3,5 @@
<string name="app_name">Android tutorial 1</string> <string name="app_name">Android tutorial 1</string>
<string name="button_play">Play</string> <string name="button_play">Play</string>
<string name="button_stop">Stop</string> <string name="button_stop">Stop</string>
<string name="button_select">Select</string>
</resources> </resources>

View file

@ -22,8 +22,13 @@ import java.util.TimeZone;
import com.gst_sdk.GStreamer; import com.gst_sdk.GStreamer;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log; import android.util.Log;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
@ -54,10 +59,11 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee
private Bundle initialization_data; private Bundle initialization_data;
private final String mediaUri = "http://docs.gstreamer.com/media/sintel_trailer-480p.ogv"; private String mediaUri = "http://docs.gstreamer.com/media/sintel_trailer-480p.ogv";
static private final int PICK_FILE_CODE = 1;
/* Called when the activity is first created. /* Called when the activity is first created. */
@Override */ @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -88,6 +94,15 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee
} }
}); });
ImageButton select = (ImageButton) this.findViewById(R.id.button_select);
select.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_PICK);
i.setDataAndType(Uri.fromFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)), "video/*;audio/*");
startActivityForResult(i, PICK_FILE_CODE);
}
});
SurfaceView sv = (SurfaceView) this.findViewById(R.id.surface_video); SurfaceView sv = (SurfaceView) this.findViewById(R.id.surface_video);
SurfaceHolder sh = sv.getHolder(); SurfaceHolder sh = sv.getHolder();
sh.addCallback(this); sh.addCallback(this);
@ -104,10 +119,11 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee
} }
protected void onSaveInstanceState (Bundle outState) { protected void onSaveInstanceState (Bundle outState) {
Log.d ("GStreamer", "Saving state, playing:" + is_playing_desired + " position:" + position); Log.d ("GStreamer", "Saving state, playing:" + is_playing_desired + " position:" + position + " uri: " + mediaUri);
outState.putBoolean("playing", is_playing_desired); outState.putBoolean("playing", is_playing_desired);
outState.putInt("position", position); outState.putInt("position", position);
outState.putInt("duration", duration); outState.putInt("duration", duration);
outState.putString("mediaUri", mediaUri);
} }
protected void onDestroy() { protected void onDestroy() {
@ -125,26 +141,29 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee
}); });
} }
/* Called from native code */ private void setMediaUri() {
private void onGStreamerInitialized () {
nativeSetUri (mediaUri); nativeSetUri (mediaUri);
if (mediaUri.startsWith("file://")) is_local_media = true; if (mediaUri.startsWith("file://")) is_local_media = true;
}
/* Called from native code */
private void onGStreamerInitialized () {
if (initialization_data != null) { if (initialization_data != null) {
is_playing_desired = initialization_data.getBoolean("playing"); is_playing_desired = initialization_data.getBoolean("playing");
int milliseconds = initialization_data.getInt("position"); int milliseconds = initialization_data.getInt("position");
Log.i ("GStreamer", "Restoring state, playing:" + is_playing_desired + " position:" + milliseconds + " ms."); Log.i ("GStreamer", "Restoring state, playing:" + is_playing_desired + " position:" + milliseconds + " ms.");
mediaUri = initialization_data.getString ("mediaUri");
/* Actually, move to one millisecond in the future. Otherwise, due to rounding errors between the /* Actually, move to one millisecond in the future. Otherwise, due to rounding errors between the
* milliseconds used here and the nanoseconds used by GStreamer, we would be jumping a bit behind * milliseconds used here and the nanoseconds used by GStreamer, we would be jumping a bit behind
* where we were before. This, combined with seeking to keyframe positions, would skip one keyframe * where we were before. This, combined with seeking to keyframe positions, would skip one keyframe
* backwards on each iteration. * backwards on each iteration.
*/ */
nativeSetPosition(milliseconds + 1); nativeSetPosition(milliseconds + 1);
if (is_playing_desired) { }
nativePlay();
} else { setMediaUri ();
nativePause(); if (is_playing_desired) {
} nativePlay();
} else { } else {
nativePause(); nativePause();
} }
@ -244,4 +263,17 @@ public class Tutorial1 extends Activity implements SurfaceHolder.Callback, OnSee
if (!is_local_media) nativeSetPosition(desired_position); if (!is_local_media) nativeSetPosition(desired_position);
if (is_playing_desired) nativePlay(); if (is_playing_desired) nativePlay();
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK && requestCode == PICK_FILE_CODE) {
String[] proj = { MediaStore.Video.Media.DATA };
Cursor c = managedQuery(data.getData(), proj, null, null, null);
int column_index = c.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
c.moveToFirst();
mediaUri = "file://" + c.getString(column_index);
setMediaUri();
}
}
} }