2016-04-19 21 views
0

私のAndroid搭載アプリケーションにビデオプレーヤー(ExoPlayer)を実装したいと思います。プレイヤーはいくつかのURLからビデオを再生する必要があります(大きくない、約2-3分)。ネクサス5ではうまく動作しますが、残念ながら電話「Samsung GT-I8552 Galaxy Win」では動作しません。アプリケーションのコンパイルと起動後に例外ログがあります。ExoPlayerは一部のデバイスで動作しません

内部実行時エラーです。
android.media.MediaCodec.dequeueOutputBufferでjava.lang.IllegalStateException

(ネイティブメソッド)

そして、これは私のコードです:

 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

ExoPlayerは、最小限のSDKレベル16の要件を持っています。

ExoPlayerの標準オーディオおよびビデオコンポーネントは、Android 4.1(APIレベル16)でリリースされたAndroidのMediaCodec APIに依存しています。したがって、以前のバージョンのAndroidでは動作しません。
投稿者:https://google.github.io/ExoPlayer/guide.html

関連する問題