안드로이드 Jetpack의 Media3에 포함된
ExoPlayer를 사용하여 RTSP 스트리밍을 진행해본다.
공식 문서 ↓
연결할 네트워크 스트림 주소는 다음과 같다.
rtsp://210.99.70.120:1935/live/cctv048.stream
공공 데이터 포털에서 제공해주는 교통정보 CCTV 스트림 주소다.
✅ Manifest 권한 추가
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
네트워크 스트리밍을 진행할 것이기에 인터넷 권한을 추가해주자.
✅ 의존성 설정
build.gradle.kts (Module:app)
implementation("androidx.media3:media3-exoplayer:1.4.1")
implementation("androidx.media3:media3-exoplayer-ui:1.4.1")
implementation("androidx.media3:media3-exoplayer-rtsp:1.4.1")
안드로이드 공식 동영상 플레이어라지만, 의존성을 추가해줘야 한다.
ExoPlayer는 기본적으로 추가해주고, UI도 추가해줘야 한다.
ExoPlayer가 Media3에 통합되면서 Media3-UI를 별개로 구분하는 듯한 느낌이다.
또한 ExoPlayer로 RTSP 통신을 구현하려면, RTSP 의존성을 별도로 추가해줘야 한다.
✅ 레이아웃 설정
activity_main.xml
<androidx.media3.ui.PlayerView
android:id="@+id/playerview"
android:layout_width="match_parent"
android:layout_height="300dp"
app:use_controller="false"
app:show_buffering="never"
/>
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@color/white"
/>
ExoPlayer를 이용하기 위해서는 Media3의 PlayerView를 사용해야 한다.
설정한 속성 2개를 간단히 설명하자면
- use_controller="false"
동영상 컨트롤러를 표시하지 않는 설정이다.
어차피 '실시간' 스트리밍이기 때문에, 재생 · 정지 등의 버튼이 불필요하다.
필요한 사람은 사용해도 무방하다.
- show_buffering="never"
버퍼링 중 프로그래스바를 표시하지 않는 설정이다.
PlayerView에 적용된 기본 프로그래스바는 회색인데, 눈에 잘 띄지 않아서 과감히 버린다.
대신, 위 처럼 별도의 프로그래스바를 직접 만들어주면 된다.
✅ RTSP 스트리밍
스트리밍에 필요한 코드는 다음과 같다.
private fun exoPlayerInit() {
// 네트워크 스트림 주소를 Uri 형식으로 초기화
val uri = "rtsp://210.99.70.120:1935/live/cctv048.stream".toUri()
// ExoPlayer 초기화
val player = ExoPlayer.Builder(this).build()
// 레이아웃에 선언한 PlayerView에 ExoPlayer 초기화
bind.playerview.player = player
// ExoPlayer에 Uri를 포함한 MediaItem 세팅
player.setMediaItem(MediaItem.fromUri(uri))
// ExoPlayer 준비
player.prepare()
// ExoPlayer 준비 완료되면 자동으로 재생
player.playWhenReady = true
// ExoPlayer에 장착하는 콜백 리스너들
player.addListener(object: Player.Listener {
// 재생 상태 변경 시 호출
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
// 재생 상태에 따라 프로그래스바 가시성 변경
bind.progressbar.visibility = if (isPlaying) View.GONE else View.VISIBLE
}
// 에러 발생 시 호출
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
// 예외처리 코드 작성
}
})
}
코드 한 줄마다 주석을 작성했으니 확인하기 바란다.
참고로, ExoPlayer에 장착하는 콜백 리스너의 종류는 정말 많다.
예시로 2개만 장착했을 뿐이다.
상황에 맞게 원하는 콜백 리스너를 사용해주면 될 것 같다.
주석을 제외한 메인 액티비티의 전체 코드는 다음과 같다.
MainActivity.kt
private lateinit var bind: ActivityMainBinding
override fun onCreate() {
...
bind = ActivityMainBinding.inflate(layoutInflater)
setContentView(bind.root)
exoPlayerInit()
}
private fun exoPlayerInit() {
val uri = "rtsp://210.99.70.120:1935/live/cctv048.stream".toUri()
val player = ExoPlayer.Builder(this).build()
bind.playerview.player = player
player.setMediaItem(MediaItem.fromUri(uri))
player.prepare()
player.playWhenReady = true
player.addListener(object: Player.Listener {
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
bind.progressbar.visibility = if (isPlaying) View.GONE else View.VISIBLE
}
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
// 예외처리
}
})
}
✅ 결과
● 스트리밍 연결 중
onIsPlayingChanged 콜백이 true로 도착할 때까지
검정 배경화면에 프로그래스바가 표시된다.
● 스트리밍 연결 성공 후
프로그래스바가 사라지며 영상이 출력되는 모습이다.
✅ RTSP 스트리밍 로그 확인하기
번외로, ExoPlayer에 MediaItem을 직접 세팅하지 않고
MediaSource를 세팅하면 더 많은 맞춤 옵션을 설정할 수 있다.
// player.setMediaItem(MediaItem.fromUri(uri))
val mediaItem = MediaItem.fromUri(uri)
val mediaSource = RtspMediaSource.Factory().setDebugLoggingEnabled(true).createMediaSource(mediaItem)
player.setMediaSource(mediaSource)
위 처럼 MediaSource를 사용하여 디버그로깅 설정을 해주면
다음과 같이 RTSP 통신이 이루어지는 과정을 로그로 확인할 수 있다.
지난 포스팅에서 공부했었던 RTSP 명령어대로
클라이언트와 서버간 요청과 응답이 이루어지고 있는 것을 확인할 수 있다.
ExoPlayer 사용하면서 느껴진 건, 확실히 공식 라이브러리라서 그런지
사용성이 정말 편리했고 다양한 기능을 제공받을 수 있어서 좋았다.
'Android (안드로이드)' 카테고리의 다른 글
[Android] 안드로이드 환경에서 C언어 사용 이유? / Java · C 성능 차이점 (5) | 2024.12.02 |
---|---|
[Android] libvlc - RTSP 스트리밍 연결 (7) | 2024.11.29 |
[Android] RTSP - 실시간 스트리밍 프로토콜 (0) | 2024.11.27 |
[Android] 앱에서 카메라로 사진 찍고 갤러리에 저장하기 / 이미지뷰 로드하기 (1) | 2024.11.26 |
[Android] 화면 스크린샷 찍고 갤러리에 저장하기 (0) | 2024.11.25 |