diff --git a/app/build.gradle b/app/build.gradle index 9f09d10..74e9cf2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,15 +6,15 @@ plugins { android { signingConfigs { digiview { - try{ - storeFile file(digiviewStoreFile) - storePassword digiviewStorePassword - keyPassword digiviewKeyPassword - keyAlias digiviewKeyAlias - } - catch (ex) { - println("You should define mStoreFile, mStorePassword, mKeyPassword and mKeyAlias in ~/.gradle/gradle.properties : "+ ex.message) - } + try{ + storeFile file(digiviewStoreFile) + storePassword digiviewStorePassword + keyPassword digiviewKeyPassword + keyAlias digiviewKeyAlias + } + catch (ex) { + println("You should define mStoreFile, mStorePassword, mKeyPassword and mKeyAlias in ~/.gradle/gradle.properties : "+ ex.message) + } } } @@ -65,7 +65,6 @@ android { } dependencies { - implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' diff --git a/app/src/main/java/com/fpvout/digiview/MainActivity.java b/app/src/main/java/com/fpvout/digiview/MainActivity.java index af1f600..44bea20 100644 --- a/app/src/main/java/com/fpvout/digiview/MainActivity.java +++ b/app/src/main/java/com/fpvout/digiview/MainActivity.java @@ -1,7 +1,5 @@ package com.fpvout.digiview; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.LayoutTransition; import android.content.Context; import android.content.Intent; @@ -10,7 +8,6 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.Bundle; -import android.os.Handler; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; @@ -24,17 +21,19 @@ import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import androidx.preference.PreferenceManager; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import io.sentry.SentryLevel; import io.sentry.android.core.SentryAndroid; import static com.fpvout.digiview.UsbMaskConnection.ACTION_USB_PERMISSION; -import static com.fpvout.digiview.VideoReaderExoplayer.VideoZoomedIn; public class MainActivity extends AppCompatActivity implements UsbDeviceListener { private static final String TAG = "DIGIVIEW"; @@ -47,13 +46,18 @@ public class MainActivity extends AppCompatActivity implements UsbDeviceListener boolean usbConnected = false; SurfaceView fpvView; private int shortAnimationDuration; - private float buttonAlpha = 1; - private View settingsButton; + private FloatingActionButton settingsButton; private View watermarkView; private OverlayView overlayView; private GestureDetector gestureDetector; private ScaleGestureDetector scaleGestureDetector; private SharedPreferences sharedPreferences; + private final Runnable hideButtonsRunnable = new Runnable() { + @Override + public void run() { + toggleView(settingsButton, false); + } + }; @Override protected void onCreate(Bundle savedInstanceState) { @@ -97,7 +101,7 @@ protected void onCreate(Bundle savedInstanceState) { }); mVideoReader = new VideoReaderExoplayer(fpvView, this); - mVideoReader.setVideoPlayingEventListener(this::hideOverlay); + mVideoReader.setVideoPlayingEventListener(this::hideFullOverlay); mVideoReader.setVideoWaitingEventListener(() -> showOverlay(R.string.waiting_for_video, OverlayStatus.Connected)); mUsbMaskConnection = new UsbMaskConnection(); @@ -132,7 +136,7 @@ private void setupGestureDetectors() { gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapConfirmed(MotionEvent e) { - toggleSettingsButton(); + toggleFullOverlay(); return super.onSingleTapConfirmed(e); } @@ -163,94 +167,78 @@ public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } - private void updateWatermark() { - if (overlayView.getVisibility() == View.VISIBLE) { - watermarkView.setAlpha(0); - return; - } + private void toggleFullOverlay() { + if (overlayView.getAlpha() > 0.0f) return; - if (sharedPreferences.getBoolean(ShowWatermark, true)) { - watermarkView.setAlpha(0.3F); - } else { - watermarkView.setAlpha(0F); - } + toggleView(settingsButton, hideButtonsRunnable); } - private void updateVideoZoom() { - if (sharedPreferences.getBoolean(VideoZoomedIn, true)) { - mVideoReader.zoomIn(); - } else { - mVideoReader.zoomOut(); - } - } + private void hideFullOverlay() { + toggleView(watermarkView, sharedPreferences.getBoolean(ShowWatermark, true), 0.3f); - private void cancelButtonAnimation() { - Handler handler = settingsButton.getHandler(); - if (handler != null) { - handler.removeCallbacksAndMessages(null); - } + toggleView(settingsButton, false); + toggleView(overlayView, false); } -// private void showSettingsButton() { -// cancelButtonAnimation(); -// -// if (overlayView.getVisibility() == View.VISIBLE) { -// buttonAlpha = 1; -// settingsButton.setAlpha(1); -// } -// } + private void showFullOverlay() { + toggleView(watermarkView, false); - private void toggleSettingsButton() { - if (buttonAlpha == 1 && overlayView.getVisibility() == View.VISIBLE) return; + toggleView(settingsButton, true); + } - // cancel any pending delayed animations first - cancelButtonAnimation(); + private void showOverlay(int textId, OverlayStatus connected) { + toggleView(overlayView, true); + showFullOverlay(); + overlayView.show(textId, connected); + } - if (buttonAlpha == 1) { - buttonAlpha = 0; - } else { - buttonAlpha = 1; - } + private void toggleView(FloatingActionButton view, @Nullable Runnable runnable) { + toggleView(view, view.getVisibility() != View.VISIBLE, runnable); + } - settingsButton.animate() - .alpha(buttonAlpha) - .setDuration(shortAnimationDuration) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - autoHideSettingsButton(); - } - }); + private void toggleView(View view, boolean visible) { + toggleView(view, visible, 1.0f, null); } - private void autoHideSettingsButton() { - if (overlayView.getVisibility() == View.VISIBLE) return; - if (buttonAlpha == 0) return; + private void toggleView(FloatingActionButton view, boolean visible) { + toggleView(view, visible, null); + } + + private void toggleView(View view, boolean visible, float visibleAlpha) { + toggleView(view, visible, visibleAlpha, null); + } - settingsButton.postDelayed(() -> { - buttonAlpha = 0; - settingsButton.animate() + private void toggleView(View view, boolean visible, float visibleAlpha, @Nullable Runnable runnable) { + if (!visible) { + view.removeCallbacks(runnable); + view.animate().cancel(); + view.animate() .alpha(0) + .setDuration(shortAnimationDuration) + .setListener(null); + } else { + view.removeCallbacks(runnable); + view.animate().cancel(); + view.animate() + .alpha(visibleAlpha) .setDuration(shortAnimationDuration); - }, 3000); + view.postDelayed(runnable, 3000); + } } - private void showOverlay(int textId, OverlayStatus connected) { - overlayView.show(textId, connected); - updateWatermark(); - autoHideSettingsButton(); - updateVideoZoom(); - - } + private void toggleView(FloatingActionButton view, boolean visible, @Nullable Runnable runnable) { + if (view.getHandler() != null) { + view.getHandler().removeCallbacksAndMessages(null); + } - private void hideOverlay() { - overlayView.hide(); - updateWatermark(); - autoHideSettingsButton(); - updateVideoZoom(); + if (!visible) { + view.hide(); + } else { + view.show(); + view.postDelayed(runnable, 3000); + } } - @Override public void usbDeviceApproved(UsbDevice device) { Log.i(TAG, "USB - usbDevice approved"); @@ -266,15 +254,11 @@ public void usbDeviceDetached() { this.onStop(); } - private void connect() { usbConnected = true; mUsbMaskConnection.setUsbDevice(usbManager, usbDevice); mVideoReader.setUsbMaskConnection(mUsbMaskConnection); - overlayView.hide(); mVideoReader.start(); - updateWatermark(); - autoHideSettingsButton(); showOverlay(R.string.waiting_for_video, OverlayStatus.Connected); } @@ -295,11 +279,6 @@ public void onResume() { showOverlay(R.string.waiting_for_usb_device, OverlayStatus.Disconnected); } } - - settingsButton.setAlpha(1); - autoHideSettingsButton(); - updateWatermark(); - updateVideoZoom(); } diff --git a/app/src/main/java/com/fpvout/digiview/OverlayView.java b/app/src/main/java/com/fpvout/digiview/OverlayView.java index 8a6c736..305dab9 100644 --- a/app/src/main/java/com/fpvout/digiview/OverlayView.java +++ b/app/src/main/java/com/fpvout/digiview/OverlayView.java @@ -2,7 +2,6 @@ import android.content.Context; import android.util.AttributeSet; -import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -22,18 +21,11 @@ public OverlayView(Context context, AttributeSet attrs) { imageView = findViewById(R.id.backdrop_image); } - public void hide(){ - setVisibility(View.GONE); - } - public void show(int textResourceId, OverlayStatus status){ showInfo(getContext().getString(textResourceId), status); } private void showInfo(String text, OverlayStatus status){ - - setVisibility(View.VISIBLE); - textView.setText(text); int image = R.drawable.ic_goggles_white; diff --git a/app/src/main/java/com/fpvout/digiview/VideoReaderExoplayer.java b/app/src/main/java/com/fpvout/digiview/VideoReaderExoplayer.java index 8e340e6..571639a 100644 --- a/app/src/main/java/com/fpvout/digiview/VideoReaderExoplayer.java +++ b/app/src/main/java/com/fpvout/digiview/VideoReaderExoplayer.java @@ -87,14 +87,14 @@ public void start() { default: return new VideoStreamServiceDataSource(dataSpec, mUsbMaskConnection.getVideoStreamService()); } - }; + }; - ExtractorsFactory extractorsFactory = () ->new Extractor[] {new H264Extractor(performancePreset.h264ReaderMaxSyncFrameSize, performancePreset.h264ReaderSampleTime)}; - MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).createMediaSource(MediaItem.fromUri(Uri.EMPTY)); - mPlayer.setMediaSource(mediaSource); + ExtractorsFactory extractorsFactory = () -> new Extractor[]{new H264Extractor(performancePreset.h264ReaderMaxSyncFrameSize, performancePreset.h264ReaderSampleTime)}; + MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).createMediaSource(MediaItem.fromUri(Uri.EMPTY)); + mPlayer.setMediaSource(mediaSource); - mPlayer.prepare(); - mPlayer.play(); + mPlayer.prepare(); + mPlayer.play(); mPlayer.addListener(new Player.Listener() { @Override public void onPlayerError(@NonNull ExoPlaybackException error) { @@ -108,12 +108,12 @@ public void onPlayerError(@NonNull ExoPlaybackException error) { break; case ExoPlaybackException.TYPE_RENDERER: Log.e(TAG, "PLAYER_SOURCE - TYPE_RENDERER: " + error.getSourceException().getMessage()); - break; - case ExoPlaybackException.TYPE_UNEXPECTED: - Log.e(TAG, "PLAYER_SOURCE - TYPE_UNEXPECTED: " + error.getSourceException().getMessage()); - break; - } + break; + case ExoPlaybackException.TYPE_UNEXPECTED: + Log.e(TAG, "PLAYER_SOURCE - TYPE_UNEXPECTED: " + error.getSourceException().getMessage()); + break; } + } @Override public void onPlaybackStateChanged(int state) { @@ -127,10 +127,10 @@ public void onPlaybackStateChanged(int state) { if (videoWaitingListener != null) videoWaitingListener.onVideoWaiting(); // let MainActivity know so it can hide watermark/show settings button (new Handler(Looper.getMainLooper())).postDelayed(() -> restart(), 1000); - break; - } + break; } - }); + } + }); mPlayer.addVideoListener(new Player.Listener() { @Override @@ -148,7 +148,7 @@ public void onVideoSizeChanged(@NonNull VideoSize videosize) { surfaceView.setLayoutParams(params); } } - }); + }); } public void toggleZoom() { @@ -167,32 +167,32 @@ public void toggleZoom() { Format videoFormat = mPlayer.getVideoFormat(); if (videoFormat == null) return; - params.dimensionRatio = videoFormat.width + ":" + videoFormat.height; - } - - surfaceView.setLayoutParams(params); + params.dimensionRatio = videoFormat.width + ":" + videoFormat.height; } - public void zoomIn() { - if (!zoomedIn) { - toggleZoom(); - } + surfaceView.setLayoutParams(params); + } + + public void zoomIn() { + if (!zoomedIn) { + toggleZoom(); } + } - public void zoomOut() { - if (zoomedIn) { - toggleZoom(); - } + public void zoomOut() { + if (zoomedIn) { + toggleZoom(); } + } - public void restart() { - mPlayer.release(); + public void restart() { + mPlayer.release(); - if (mUsbMaskConnection.isReady()) { - mUsbMaskConnection.start(); - start(); - } + if (mUsbMaskConnection.isReady()) { + mUsbMaskConnection.start(); + start(); } + } public void stop() { if (mPlayer != null) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3d2145d..3f8df06 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -19,6 +19,15 @@ app:layout_constraintTop_toTopOf="parent"> + + - - @string/video_preset_default @string/video_preset_conservative