最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - How to change Exo player decoding or use HardwareBuffer - Stack Overflow

programmeradmin3浏览0评论

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
Add a comment  | 

1 Answer 1

Reset to default 0

The 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).

发布评论

评论列表(0)

  1. 暂无评论