I'm developing an Android app that requires the ability to play videos with quick pause and play functionality.
The app needs to play a specific 1000ms segment of the video.
However, I'm encountering an issue with ExoPlayer. It struggles to handle videos with very short durations—when I attempt to play such segments, the video freezes on a frame while the audio plays without any issues.
Do you have any idea how to fix it?
I think i need to play my video with Hardware decoding to fix it
But i don't know how
Or the problem is my code: The way that i created the player:
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
.setRendererDisabled(C.TRACK_TYPE_VIDEO, true)
.clearOverridesOfType(C.TRACK_TYPE_VIDEO)
.build()
);
player = new ExoPlayer.Builder(context)
.setTrackSelector(trackSelector)
.build();
playerView.setPlayer(player);
playerView.setUseController(false);
MediaItem mediaItem = new MediaItem.Builder()
.setUri(videoUri)
.build();
player.setMediaItem(mediaItem);
player.prepare();
The task that sometimes has issue: the video freezes on a frame while the audio plays without any issues
playerView.setOnClickListener(view -> {
playCurrent();
});
playCurrent()
public void playCurrent(){
if (!player.isPlaying()) {
SubRipParserUtil.SubtitleEntry previousSubtitle = parser.getPreviousSubtitle(subtitle.countOfSubtitles,false);
if (previousSubtitle != null && subtitle.startTimeMs - previousSubtitle.endTimeMs > START_EXPAND_TIME) // if last subtitle was not close to current one, start the current play START_EXPAND_TIME Further back
player.seekTo(subtitle.startTimeMs - START_EXPAND_TIME);
else
player.seekTo(subtitle.startTimeMs);
endTimeMs = subtitle.endTimeMs;
player.play();
}
}
player Listener
player.addListener(new Player.Listener() {
@Override
public void onIsPlayingChanged(boolean isPlaying) {
if (isPlaying){
long duration = endTimeMs - player.getCurrentPosition();
handler.postDelayed(stopRunnable, duration);
}
Player.Listener.super.onIsPlayingChanged(isPlaying);
}
});
stopRunnable
stopRunnable = () -> {
if (player.isPlaying()) {
player.pause();
}
};
XML
<androidx.media3.ui.PlayerView
android:id="@+id/playerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:layout_height="220dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/whatToDoTextView"
android:layout_marginTop="8dp"
/>
I'm developing an Android app that requires the ability to play videos with quick pause and play functionality.
The app needs to play a specific 1000ms segment of the video.
However, I'm encountering an issue with ExoPlayer. It struggles to handle videos with very short durations—when I attempt to play such segments, the video freezes on a frame while the audio plays without any issues.
Do you have any idea how to fix it?
I think i need to play my video with Hardware decoding to fix it
But i don't know how
Or the problem is my code: The way that i created the player:
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
.setRendererDisabled(C.TRACK_TYPE_VIDEO, true)
.clearOverridesOfType(C.TRACK_TYPE_VIDEO)
.build()
);
player = new ExoPlayer.Builder(context)
.setTrackSelector(trackSelector)
.build();
playerView.setPlayer(player);
playerView.setUseController(false);
MediaItem mediaItem = new MediaItem.Builder()
.setUri(videoUri)
.build();
player.setMediaItem(mediaItem);
player.prepare();
The task that sometimes has issue: the video freezes on a frame while the audio plays without any issues
playerView.setOnClickListener(view -> {
playCurrent();
});
playCurrent()
public void playCurrent(){
if (!player.isPlaying()) {
SubRipParserUtil.SubtitleEntry previousSubtitle = parser.getPreviousSubtitle(subtitle.countOfSubtitles,false);
if (previousSubtitle != null && subtitle.startTimeMs - previousSubtitle.endTimeMs > START_EXPAND_TIME) // if last subtitle was not close to current one, start the current play START_EXPAND_TIME Further back
player.seekTo(subtitle.startTimeMs - START_EXPAND_TIME);
else
player.seekTo(subtitle.startTimeMs);
endTimeMs = subtitle.endTimeMs;
player.play();
}
}
player Listener
player.addListener(new Player.Listener() {
@Override
public void onIsPlayingChanged(boolean isPlaying) {
if (isPlaying){
long duration = endTimeMs - player.getCurrentPosition();
handler.postDelayed(stopRunnable, duration);
}
Player.Listener.super.onIsPlayingChanged(isPlaying);
}
});
stopRunnable
stopRunnable = () -> {
if (player.isPlaying()) {
player.pause();
}
};
XML
<androidx.media3.ui.PlayerView
android:id="@+id/playerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:layout_height="220dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/whatToDoTextView"
android:layout_marginTop="8dp"
/>
Share
Improve this question
edited Jan 19 at 18:33
ahmadreza gh
asked Jan 19 at 0:16
ahmadreza ghahmadreza gh
11 bronze badge
1
- Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Bot Commented Jan 19 at 9:35
1 Answer
Reset to default 0The ability to use hardware-accelerated decoding depends on a few factors:
Whether the combination of compression algorithm, width, height, frame rate, bitrate, color format is supported by the specific device. There are some minimum requirements listed in the Android Compatibility Definition Document. But beyond those the support varies among devices.
Whether there is enough memory available for a hardware codec. This is usually shared memory, so it can be affected by other processes.
Even if the player can use a hardware codec, launching one still takes some time. So if you want to minimize the playback latency consider preparing the player ahead of time (several milliseconds before you need to play it).