Skip to content

Commit

Permalink
feat(android): add settings button to control video playback speed (T…
Browse files Browse the repository at this point in the history
  • Loading branch information
seyedmostafahasani authored Oct 5, 2024
1 parent d81e6ea commit d1883a7
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.facebook.react.bridge.ReadableMap
class ControlsConfig {
var hideSeekBar: Boolean = false
var hideDuration: Boolean = false

var hidePosition: Boolean = false
var hidePlayPause: Boolean = false
var hideForward: Boolean = false
Expand All @@ -17,6 +16,7 @@ class ControlsConfig {
var hideNavigationBarOnFullScreenMode: Boolean = true
var hideNotificationBarOnFullScreenMode: Boolean = true
var liveLabel: String? = null
var hideSettingButton: Boolean = true

var seekIncrementMS: Int = 10000

Expand All @@ -39,6 +39,7 @@ class ControlsConfig {
config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(controlsConfig, "hideNavigationBarOnFullScreenMode", true)
config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(controlsConfig, "hideNotificationBarOnFullScreenMode", true)
config.liveLabel = ReactBridgeUtils.safeGetString(controlsConfig, "liveLabel", null)
config.hideSettingButton = ReactBridgeUtils.safeGetBool(controlsConfig, "hideSettingButton", true)
}
return config
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -99,7 +100,6 @@
import androidx.media3.extractor.metadata.id3.Id3Frame;
import androidx.media3.extractor.metadata.id3.TextInformationFrame;
import androidx.media3.session.MediaSessionService;
import androidx.media3.ui.DefaultTimeBar;
import androidx.media3.ui.LegacyPlayerControlView;

import com.brentvatne.common.api.BufferConfig;
Expand Down Expand Up @@ -258,6 +258,7 @@ public class ReactExoplayerView extends FrameLayout implements
private long lastDuration = -1;

private boolean viewHasDropped = false;
private int selectedSpeedIndex = 1; // Default is 1.0x

private final String instanceId = String.valueOf(UUID.randomUUID());

Expand Down Expand Up @@ -463,6 +464,10 @@ public void onVisibilityChange(int visibility) {
setPausedModifier(true)
);

//Handling the settingButton click event
final ImageButton settingButton = playerControlView.findViewById(R.id.exo_settings);
settingButton.setOnClickListener(v -> openSettings());

//Handling the fullScreenButton click event
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen));
Expand Down Expand Up @@ -496,6 +501,35 @@ public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
};
player.addListener(eventListener);
}
private void openSettings() {
AlertDialog.Builder builder = new AlertDialog.Builder(themedReactContext);
builder.setTitle(R.string.settings);
String[] settingsOptions = {themedReactContext.getString(R.string.playback_speed)};
builder.setItems(settingsOptions, (dialog, which) -> {
if (which == 0) {
showPlaybackSpeedOptions();
}
});
builder.show();
}

private void showPlaybackSpeedOptions() {
String[] speedOptions = {"0.5x", "1.0x", "1.5x", "2.0x"};
AlertDialog.Builder builder = new AlertDialog.Builder(themedReactContext);
builder.setTitle(R.string.select_playback_speed);

builder.setSingleChoiceItems(speedOptions, selectedSpeedIndex, (dialog, which) -> {
selectedSpeedIndex = which;
float speed = switch (which) {
case 0 -> 0.5f;
case 2 -> 1.5f;
case 3 -> 2.0f;
default -> 1.0f;
};
setRateModifier(speed);
});
builder.show();
}

/**
* Adding Player control to the frame layout
Expand Down Expand Up @@ -539,6 +573,7 @@ private void refreshControlsStyles() {
updateViewVisibility(playerControlView.findViewById(R.id.exo_position), controlsConfig.getHidePosition(), GONE);
updateViewVisibility(playerControlView.findViewById(R.id.exo_progress), controlsConfig.getHideSeekBar(), INVISIBLE);
updateViewVisibility(playerControlView.findViewById(R.id.exo_duration), controlsConfig.getHideDuration(), GONE);
updateViewVisibility(playerControlView.findViewById(R.id.exo_settings), controlsConfig.getHideSettingButton(), GONE );
}

private void updateLiveContent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@
android:includeFontPadding="false"
android:textColor="@color/silver_gray"/>

<ImageButton
android:id="@+id/exo_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/ExoStyledControls.Button.Bottom.Settings"
/>

<ImageButton
android:id="@+id/exo_fullscreen"
style="@style/ExoMediaButton.FullScreen"
Expand Down
6 changes: 6 additions & 0 deletions android/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@
<string name="error_drm_unsupported_scheme">This device does not support the required DRM scheme</string>

<string name="error_drm_unknown">An unknown DRM error occurred</string>

<string name="settings">Settings</string>

<string name="playback_speed">Playback Speed</string>

<string name="select_playback_speed">Select Playback Speed</string>
</resources>
2 changes: 2 additions & 0 deletions docs/pages/component/props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ Adjust the control styles. This prop is need only if `controls={true}` and is an
| hideDuration | boolean | The default value is `false`, allowing you to hide the duration. |
| hideNavigationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the navigation bar on full-screen mode. |
| hideNotificationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the notification bar on full-screen mode. |
| hideSettingButton | boolean | The default value is `true`, allowing you to hide the setting button. |
| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. |
| liveLabel | string | Allowing you to set a label for live video. |

Expand All @@ -175,6 +176,7 @@ controlsStyles={{
hideDuration: false,
hideNavigationBarOnFullScreenMode: true,
hideNotificationBarOnFullScreenMode: true,
hideSettingButton: true,
seekIncrementMS: 10000,
liveLabel: "LIVE"
}}
Expand Down
1 change: 1 addition & 0 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ type ControlsStyles = Readonly<{
hideDuration?: WithDefault<boolean, false>;
hideNavigationBarOnFullScreenMode?: WithDefault<boolean, true>;
hideNotificationBarOnFullScreenMode?: WithDefault<boolean, true>;
hideSettingButton?: WithDefault<boolean, true>;
seekIncrementMS?: Int32;
liveLabel?: string;
}>;
Expand Down
1 change: 1 addition & 0 deletions src/types/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export type ControlsStyles = {
hideFullscreen?: boolean;
hideNavigationBarOnFullScreenMode?: boolean;
hideNotificationBarOnFullScreenMode?: boolean;
hideSettingButton?: boolean;
seekIncrementMS?: number;
liveLabel?: string;
};
Expand Down

0 comments on commit d1883a7

Please sign in to comment.