Android 공부를 하다가 Youtube 앱은 어떻게 만들어지는 가에 대해서 궁금증이 생겨서
ExoPlayer2를 사용해보았다
ExoPlayer2 란❓
- Google이 Android SDK 와 별도로 배포되는 오픈소스 프로젝트
- 오디오 및 동영상 재생 가능
- 오디오 및 동영상 재생 관련 강력한 기능들 포함
- 유튜브 앱에서 사용하는 라이브러리
참고
https://exoplayer.dev/hello-world.html
영상 데이터는 어디서❓
- google 에서 제공하는 샘플 비디오의 json 으로 mocky를 통해서 API 를 생성❗❗
👇 아래의 json 을 조금 손질한 뒤
https://gist.github.com/jsturgis/3b19447b304616f18657
👇해당 사이트를 통해서 API 를 제작
ExoPlayer2 사용하기
0. Gradle 등록
implementation 'com.google.android.exoplayer:exoplayer:2.18.1'
1. xml 에 PlayerView 설정
<com.google.android.exoplayer2.ui.PlayerView
app:resize_mode="fill"
android:id="@+id/playerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@id/mainContainerLayout"
app:layout_constraintStart_toStartOf="@id/mainContainerLayout"
app:layout_constraintTop_toTopOf="@id/mainContainerLayout" />
2. json 구조에 맞추어 model 생성
data class VideoModel(
val title : String,
val sources : String,
val subtitle: String,
val thumb: String,
val description: String
)
data class VideoDto(
val videos: List<VideoModel>
)
3. Retrofit2를 통해서 API 호출
비디오 리스트를 RecyclerView 를 통해서 보여줄 것이기 때문에 Retrofit2를 통해서 받은 결과를 RecyclerView Adaper 에 넘겨준다
interface VideoService {
@GET("비디오uri 주소")
fun listVideo() : Call<VideoDto>
}
private fun getVideoList() {
val retrofit = Retrofit.Builder()
.baseUrl("비디오url")
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofit.create(VideoService::class.java).also {
it.listVideo()
.enqueue(object : Callback<VideoDto> {
override fun onResponse(call: Call<VideoDto>, response: Response<VideoDto>) {
if (response.isSuccessful.not()) {
Log.d("MainActivity", "response fail")
return
}
//null 이 아닐때 비디오리스트를 adapter에 추가
response.body()?.let { videoDto ->
videoAdapter.submitList(videoDto.videos)
}
}
override fun onFailure(call: Call<VideoDto>, t: Throwable) {
}
})
}
}
RecyclerVIew Adapter 의 경우는 따로 적지 않고 링크로 첨부하겠다
그리고❗❗ Retrofit2 의 사용방법은
👇 아래의 블로그에서 확인 할것
https://sju01334.tistory.com/78
4. ExoPlayer2 호출
private var player: ExoPlayer? = null
private lateinit var videoAdapter: VideoAdapter
//onCreate() 에 작성
context?.let {
player = ExoPlayer.Builder(it).build()
}
//뷰 바인딩으로 해당 view 호출
binding.playerView.player = player
//어댑터 호출과 함께 callback 함수를 인자로 보내준다
videoAdapter = VideoAdapter(callback = { url, title ->
play(url, title)
})
//뷰 바인딩으로 리사이클러뷰 호출 후 초기화
binding.fragmentRecyclerView.apply {
adapter = videoAdapter
layoutManager = LinearLayoutManager(context)
}
//재생을 위한 함수
//해당 함수를 영상 클릭시 호출해준다.
fun play(url: String, title: String) {
context?.let {
//data source 로 변환후에 media source 로 변환
val dataSourceFactory = DefaultHttpDataSource.Factory()
val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(Uri.parse(url)))
player?.setMediaSource(mediaSource)
player?.prepare()
player?.play()
}
}
뭔가,, 코드가 비대해진것 같은데 정리하자면
준비시
1. ExoPlayer2 객체를 builder() 를통해 생성하고
2. playerView 에 생성된 객체를 넣어준다.
재생시
1. datasourceFactory 에서 객체를 가져온뒤
2. MediaItem 을 uri 기반으로 생성해서
3. mediaSource 를 생성한뒤
4. player 에 넣어준다(그리고 재생!)
📌 명심해야 할 점은, MediaSource 인스턴스는 재사용되지 않는다.
그리고 ExoPlayer 를 쓰지 않을 경우는 release 해줄 것
[결과물]
재생이 잘된다..!
클릭해도 해당 영상이 잘 재생된다앗..!😲😲
조금 더 보완 할 예정
참고
https://developer.android.com/codelabs/exoplayer-intro#0
https://jungwoon.github.io/android/library/2020/11/06/ExoPlayer.html
'개발 > Android' 카테고리의 다른 글
[Android] Coroutines vs Thread (0) | 2022.08.13 |
---|---|
[Android] PendingIntent 와 getBroadcast() (0) | 2022.08.11 |
[Android] FragmentManager란? (0) | 2022.08.09 |
[Android] Vector 와 Bitmap (0) | 2022.08.08 |
[Android] DP 와 SP (0) | 2022.08.07 |
댓글