ExoPlayer不适用于某些设备

时间:2016-04-19 08:32:09

标签: android exoplayer

我想在我的Android应用中实现视频播放器(ExoPlayer)。玩家必须从某个网址播放视频(不大,约2-3分钟)。在nexus 5上运行良好,但在电话"三星GT-I8552 Galaxy Win"不幸的是它不起作用。编译和启动app后有异常日志:

内部运行时错误                                                                                                                                                                                                 java.lang.IllegalStateException

at android.media.MediaCodec.dequeueOutputBuffer(Native Method)

这是我的代码:

      private SurfaceView surfaceView;
      private ExoPlayer player;
      private MediaCodecVideoTrackRenderer videoRenderer;
      private MediaCodecAudioTrackRenderer audioRenderer;
      private CustomMediaController mediaController;
      private String userAgent;
      private final int RENDERER_COUNT = 8;
      private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
      private static final int BUFFER_SEGMENT_COUNT =  256;  
      private static final int minBufferMs = 10000;
      private static final int minRebufferMs = 5000;
      private final String videoUrl_2 = "someurl...";

...

    surfaceView = (SurfaceView) findViewById(R.id.surface_view);
    player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, minBufferMs, minRebufferMs);
    userAgent = Util.getUserAgent(this, "MyPlayer");
    Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
    DataSource dataSource = new DefaultUriDataSource(context, null, userAgent);

    ExtractorSampleSource sampleSource = new ExtractorSampleSource(Uri.parse(videoUrl_2), dataSource, allocator, BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
    videoRenderer = new MediaCodecVideoTrackRenderer(context,
            sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
    audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, MediaCodecSelector.DEFAULT);
    player.prepare(videoRenderer, audioRenderer);
    player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surfaceView.getHolder().getSurface());

    player.setPlayWhenReady(true);

    CustomMediaPlayerControl customMediaPlayerControl = new CustomMediaPlayerControl(player);
    mediaController = new CustomMediaController(context);
    mediaController.setMediaPlayer(customMediaPlayerControl);
    mediaController.setAnchorView(surfaceView);
    mediaController.setEnabled(true);

我的班级CustomMediaPlayerControl:

public class CustomMediaPlayerControl implements MediaController.MediaPlayerControl {
private ExoPlayer player;

public CustomMediaPlayerControl(ExoPlayer player) {
    this.player = player;
}

@Override
public void start() {
    player.setPlayWhenReady(true);
}

@Override
public void pause() {
    player.setPlayWhenReady(false);
}

@Override
public int getDuration() {
    return (int) player.getDuration();
}

@Override
public int getCurrentPosition() {
    return (int) player.getCurrentPosition();
}

@Override
public void seekTo(int pos) {
    player.seekTo(pos);
}

@Override
public boolean isPlaying() {
    return player.getPlayWhenReady();
}

@Override
public int getBufferPercentage() {
    return (int) player.getBufferedPercentage();
}

@Override
public boolean canPause() {
    return true;
}

@Override
public boolean canSeekBackward() {
    return true;
}

@Override
public boolean canSeekForward() {
    return true;
}

@Override
public int getAudioSessionId() {
    return 0;
}
}

我的班级CustomMediaController:

public class CustomMediaController extends MediaController {

private MediaController.MediaPlayerControl playerControl;

public CustomMediaController(Context context) {
    super(context);
}

@Override
public void setMediaPlayer(MediaController.MediaPlayerControl playerControl) {
    super.setMediaPlayer(playerControl);
    this.playerControl = playerControl;
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    int keyCode = event.getKeyCode();
    if (playerControl.canSeekForward() && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            playerControl.seekTo(playerControl.getCurrentPosition() + 15000); // milliseconds
            show();
        }
        return true;
    } else if (playerControl.canSeekBackward() && keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            playerControl.seekTo(playerControl.getCurrentPosition() - 5000); // milliseconds
            show();
        }
        return true;
    }
    return super.dispatchKeyEvent(event);
}
}

1 个答案:

答案 0 :(得分:1)

ExoPlayer对sdk 16级要求最低。

  

ExoPlayer的标准音频和视频组件依赖于Android的MediaCodec API,该API在Android 4.1(API级别16)中发布。因此,它们不适用于早期版本的Android   发件人:https://google.github.io/ExoPlayer/guide.html