티스토리 뷰
비디오를 URI로 받아와 EXO플레이어를 통해 재생하는 컨텐츠를 만들 예정이다.
엑소플레이어는 구글에서 제공하는 라이브러리로 google무비 앱 등 다양한 앱을 이것을 활용해서 만들었다고 한다.
많은 사람들이 이미 활용하는 만큼 이미 구글에 검색하면 정보가 많이 나오는데, 한글로 된 문서는 찾기 힘들어서 너무
힘들다... 지금은 재생만 가능하고 영상 리스트 선택이 안되서 그것을 하고있다.
일단 EXOPlayer를 사용하려면 demo 버전을 다운 받아서 확인해 봐야한다.
https://github.com/google/ExoPlayer
깃허브에 올라와 있는 공식 데모버전을 활용해보자.
우선 나는
DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
exoPlayerView = view.findViewById(R.id.exo_player);//exo_player ui
exoPlayerView.setControllerVisibilityListener(new PlayerControlView.VisibilityListener() {//플레이어 컨트롤러 셋팅
@Override
public void onVisibilityChange(int visibility) {
playListBtn.setVisibility(visibility);
}
});//참고사항 exoplayer는 단일쓰레드 사용, 메인 스레드를 할당해 줘서 사용하기를 권장
dataSourceFactory = new DefaultDataSourceFactory(mContext,Util.getUserAgent(mContext,"asd"), BANDWIDTH_METER);//Produces DataSource instances through which media data is loaded. 아마도 재생 데이터 선택 ?
DefaultLoadControl loadControl = new DefaultLoadControl();
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newSimpleInstance(mContext,trackSelector,loadControl);// 플레이어 설정? SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build(); 엑소플레이어에 기능을 확장할 수 있게 선언함?
player.setAudioStreamType(C.STREAM_TYPE_ALARM);//알람의 음량을 이용하여 음악을 재생한다.
player.addListener(new Player.EventListener() {//플레이어 상 이벤트에 따른 동작제어
@Override
public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
Log.d(TAG,"ontrackChange");
}
@Override
public void onLoadingChanged(boolean isLoading) {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {//플레이어 상태 변화를 받을 수 있음
Log.d(TAG,playbackState+"현재 플레이어 상태");
playListBtn.setVisibility(View.VISIBLE);
switch (playbackState) {
case Player.STATE_IDLE: // 1
//재생 실패
break;
case Player.STATE_BUFFERING: // 2
// 재생 준비 , 데이터가 로드가 덜됨
break;
case Player.STATE_READY: // 3
// 재생 준비 완료 ,즉시 재생 가능한 상태
break;
case Player.STATE_ENDED: // 4 , 재생 마침 , 재생이 완료된 상태
Intent intent = new Intent(BNS_ACTION_CONTENT_STOP);
exoPlayerView.setPlayer(null);
player.release();//플레이어 끝내기 (다른 곳에서 디코더를? 사용할 수 있게 해주기 위해 끝내줘야함)
player = null;
mContext.sendBroadcast(intent);//서버에 끝났다고 알림
if(getActivity()!=null){
getActivity().finish();//프레그먼트 없앰
}
// 재생 마침
break;
default:
break;
}
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {//등록 실패
// ///////////---------------네트워크 때문에 안된건지 확인 시작
// if (error.type == ExoPlaybackException.TYPE_SOURCE) {
// IOException cause = error.getSourceException();
// if (cause instanceof HttpDataSource.HttpDataSourceException) {
// // An HTTP error occurred.
// Toast.makeText(mContext, "네트워크 상태를 확인해주세요.", Toast.LENGTH_SHORT).show();
// HttpDataSource.HttpDataSourceException httpError = (HttpDataSource.HttpDataSourceException) cause;
// // This is the request for which the error occurred.
// DataSpec requestDataSpec = httpError.dataSpec;
// // It's possible to find out more about the error both by casting and by
// // querying the cause.
// if (httpError instanceof HttpDataSource.InvalidResponseCodeException) {
// // Cast to InvalidResponseCodeException and retrieve the response code,
// // message and headers.
// } else {
// // Try calling httpError.getCause() to retrieve the underlying cause,
// // although note that it may be null.
// }
// }
// }
// /////////---------------네트워크 때문에 안된건지 확인 끝
Toast.makeText(mContext, "비디오를 로드할 수 없습니다.", Toast.LENGTH_SHORT).show();
if(getActivity()!=null){
getActivity().finish();
}
}
@Override
public void onPositionDiscontinuity(int reason) {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
Log.d(TAG,"onPlaybackParematerCHange");
}
@Override
public void onSeekProcessed() {
}
});
exoPlayerView.setPlayer(player);//Attaching the player to a view,, Bind the player to the view
readyToVideo();
}
@Override
public void onPause() {
super.onPause();
if(player != null){
player.stop();
}
}
public static Bitmap retriveVideoFrameFromVideo(String videoPath)
throws Throwable {
Bitmap bitmap = null;
MediaMetadataRetriever mediaMetadataRetriever = null;
try {
mediaMetadataRetriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
else
mediaMetadataRetriever.setDataSource(videoPath);
bitmap = mediaMetadataRetriever.getFrameAtTime(1, MediaMetadataRetriever.OPTION_CLOSEST);
} catch (Exception e) {
e.printStackTrace();
throw new Throwable(
"Exception in retriveVideoFrameFromVideo(String videoPath)"
+ e.getMessage());
} finally {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
}
}
return bitmap;
}
private void readyToVideo(){//Preparing the player
MediaSource mediaSource = buildMediaSource(Uri.parse(uriString));//uri값을 미디어 소스로서 사용 (선택된건 안쓰네) 여기서 유튜브가 아닌건 실행하고
player.prepare(mediaSource, true, false);
//start,stop
player.setPlayWhenReady(true);
}
를 ONCREATE 안에 배치하여 영상 재생에 성공하였습니다.
코드에 대한 내용은 주석으로 간략하게 적어두었습니다.
문의사항이 있으면 댓글로 남겨주세요.
우선 플레이 리스트가 되도록 계속해서 살펴보러 가보겠습니다.
최종적으로 영상을 play 시키는 곳은
setPlayWhenReady이고
그 전에
생성된 재생목록을 받아들여서 재생시킬 것들을 넣어두는 곳이
player.prepare(mediaSource, true, false)이다
즉 미디어 소스를 다 받고
실행시켜야 한다는 소리 !
~!~!
'Web&App > 안드로이드' 카테고리의 다른 글
댓글