Android中JWPlayer添加Fast-FORWARD与REWIND按钮需求咨询
Hey there! I’ve dealt with this exact need before when working with JW Player’s Android SDK, so let me break down a solid approach for you—since the official docs don’t spell this out directly, we’ll build custom controls to handle the fast-forward/rewind actions.
Step 1: Create a Custom Layout with JWPlayer and Buttons
First, wrap the JWPlayerView with your custom control buttons in your layout file. Here’s an example using ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.longtailvideo.jwplayer.JWPlayerView android:id="@+id/jw_player_view" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <!-- Rewind Button --> <ImageButton android:id="@+id/rewind_btn" android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/ic_rewind" android:background="@android:color/transparent" android:contentDescription="Rewind 10 seconds" app:layout_constraintBottom_toBottomOf="@id/jw_player_view" app:layout_constraintStart_toStartOf="parent" app:layout_constraintMarginStart="32dp" app:layout_constraintMarginBottom="16dp"/> <!-- Fast-Forward Button --> <ImageButton android:id="@+id/fast_forward_btn" android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/ic_fast_forward" android:background="@android:color/transparent" android:contentDescription="Fast-forward 10 seconds" app:layout_constraintBottom_toBottomOf="@id/jw_player_view" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintMarginEnd="32dp" app:layout_constraintMarginBottom="16dp"/> </androidx.constraintlayout.widget.ConstraintLayout>
Step 2: Implement Click Listeners for the Buttons
In your Activity or Fragment, grab references to the JWPlayer instance and buttons, then add click logic using the seekTo() method—this is the core of handling fast-forward/rewind.
Kotlin Example:
class VideoPlayerActivity : AppCompatActivity() { private lateinit var jwPlayerView: JWPlayerView private lateinit var rewindBtn: ImageButton private lateinit var fastForwardBtn: ImageButton private val SKIP_TIME = 10000 // 10 seconds in milliseconds override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_video_player) jwPlayerView = findViewById(R.id.jw_player_view) rewindBtn = findViewById(R.id.rewind_btn) fastForwardBtn = findViewById(R.id.fast_forward_btn) // Initialize your JWPlayer with media config val mediaConfig = MediaConfig.Builder() .file("your_video_url_here") .build() jwPlayerView.player.load(mediaConfig) // Rewind click handler rewindBtn.setOnClickListener { val currentPosition = jwPlayerView.player.currentPosition val newPosition = max(0, currentPosition - SKIP_TIME) jwPlayerView.player.seekTo(newPosition) } // Fast-forward click handler fastForwardBtn.setOnClickListener { val currentPosition = jwPlayerView.player.currentPosition val duration = jwPlayerView.player.duration val newPosition = min(duration.toLong(), currentPosition + SKIP_TIME) jwPlayerView.player.seekTo(newPosition) } // Optional: Disable buttons when video isn't ready jwPlayerView.player.addOnReadyListener { rewindBtn.isEnabled = true fastForwardBtn.isEnabled = true } jwPlayerView.player.addOnErrorListener { _, _ -> rewindBtn.isEnabled = false fastForwardBtn.isEnabled = false } } override fun onPause() { super.onPause() jwPlayerView.onPause() } override fun onResume() { super.onResume() jwPlayerView.onResume() } override fun onDestroy() { jwPlayerView.onDestroy() super.onDestroy() } }
Java Example:
public class VideoPlayerActivity extends AppCompatActivity { private JWPlayerView jwPlayerView; private ImageButton rewindBtn; private ImageButton fastForwardBtn; private static final long SKIP_TIME = 10000; // 10 seconds in milliseconds @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_player); jwPlayerView = findViewById(R.id.jw_player_view); rewindBtn = findViewById(R.id.rewind_btn); fastForwardBtn = findViewById(R.id.fast_forward_btn); // Initialize JWPlayer with media config MediaConfig mediaConfig = new MediaConfig.Builder() .file("your_video_url_here") .build(); jwPlayerView.getPlayer().load(mediaConfig); // Rewind click listener rewindBtn.setOnClickListener(v -> { long currentPosition = jwPlayerView.getPlayer().getCurrentPosition(); long newPosition = Math.max(0, currentPosition - SKIP_TIME); jwPlayerView.getPlayer().seekTo(newPosition); }); // Fast-forward click listener fastForwardBtn.setOnClickListener(v -> { long currentPosition = jwPlayerView.getPlayer().getCurrentPosition(); long duration = jwPlayerView.getPlayer().getDuration(); long newPosition = Math.min(duration, currentPosition + SKIP_TIME); jwPlayerView.getPlayer().seekTo(newPosition); }); // Optional: Toggle button state based on video readiness jwPlayerView.getPlayer().addOnReadyListener(() -> { rewindBtn.setEnabled(true); fastForwardBtn.setEnabled(true); }); jwPlayerView.getPlayer().addOnErrorListener((player, error) -> { rewindBtn.setEnabled(false); fastForwardBtn.setEnabled(false); return false; }); } @Override protected void onPause() { super.onPause(); jwPlayerView.onPause(); } @Override protected void onResume() { super.onResume(); jwPlayerView.onResume(); } @Override protected void onDestroy() { jwPlayerView.onDestroy(); super.onDestroy(); } }
Key Notes:
- Adjust the
SKIP_TIMEvalue to whatever interval you want (e.g., 15000 for 15 seconds). - The
seekTo()method works perfectly here because it directly jumps the playback position—JW Player handles the rest of the playback sync. - Adding the ready/error listeners ensures the buttons only work when the video is in a playable state, which improves user experience.
This approach is lightweight and integrates seamlessly with JW Player’s existing functionality—no need to mess with the SDK’s internal controls.
内容的提问来源于stack exchange,提问作者lara

