Skip to content

⚙ [기술 검토] ExoPlayer 사용여부

박봉팔 edited this page Dec 4, 2024 · 1 revision

ExoPlayer를 사용해야 하는지에 대한 기술 결정 과정

🔍 ExoPlayer를 사용하려는 이유

  • androidx.media3:media3-exoplayer:1.4.0-rc01 부터 Image Slide를 제공해준다고 함.
  • 추후에 Image, Video를 모두 지원하는 앱으로 변경이 되었을 때를 대비해서 한 번에 처리할 수 있을 것이라고 기대가 됨.
  • 해리포터의 움직이는 그림처럼 동작하게 하여 사용자에게 즐거움을 주고싶음.

❓ ExoPlayer

  • 동영상 및 오디오 파일의 재생을 허용하는 app 수준 미디어 플레이어
  • ExoPlayer는 MediaPlayer와 동일한 미디어 형식을 다수 지원하며 DASH, SmoothStreaming과 같은 적응형 형식도 지원
  • 맞춤설정 가능성과 확장성이 매우 높음. Play Store 업데이트를 통해 업데이트 가능
  • MediaPlayer와 달리 여러 스트리밍 포로토콜 지원, 기본 오디오 및 동영상 renderer, 미디어 버퍼링을 처리하는 구성요소와 같은 편의성을 가짐

2️⃣ 리서칭

공식 문서를 읽어본 결과 이미지 지원은 주로 동영상이나 오디오 콘텐츠와 함께 사용할 이미지를 처리하기 위한 목적으로 제공되는 기능.

예를 들어, 동영상이 재생되지 않거나 로딩 중일 때 미리보기 이미지(thumbnail)를 보여주거나, 동영상에서 특정 시간의 이미지를 캡처하거나 오디오 재생 시 앨범 표지 이미지를 표시하는 데 활용.

ExoPlayer의 이미지 기능은 이미지가 메인 콘텐츠가 아닌, 다른 미디어와 결합된 콘텐츠에서 보조 역할을 할 때 유용하다. 이를 통해 비디오와 오디오 재생에 연관된 다양한 이미지 처리를 ExoPlayer 내부에서 일관되게 처리할 수 있다.

또, 이미지 슬라이드 쇼 기능도 지원한다. 이는 주로 슬라이드 쇼와 같은 이미지 콘텐츠를 처리할 때 사용되며, ExoPlayer의 SimpleExoPlayer 클래스를 이용하여 이미지 리스트를 슬라이드 쇼처럼 순차적으로 표시할 수 있다.

이미지 슬라이드 쇼를 구현하는 방식 ⇒ 이미지의 리스트를 시간에 따라 자동으로 넘겨주는 방식. ExoPlayer의 MediaItem 을 사용하여 이미지 파일들을 순차적으로 재생하거나, 이미지 URL을 통해 이미지를 로딩할 수도 있음.

하지만 이 기능은 주로 비디오 재생을 위한 라이브러리의 일부로 구현됨. 따라서 Glide, Coil, Pager를 쓰는 것보다 기본적인 미디어 재생에 필요한 기본적인 이미지 슬라이드를 처리하는 기능을 제공하는 수준임.

ExoPlayer의 네트워크 처리를 위한 사용?

ExoPlayer는 미디어 로딩 상태 관리를 통해 네트워크 에러 시 대체 이미지 또는 재시도 로직을 구현할 수 있다.

@Composable
fun MediaImageContent(
    imageUrl: String,
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val exoPlayer = remember {
        ExoPlayer.Builder(context).build().apply {
            // 이미지 소스 설정
            val mediaItem = MediaItem.Builder()
                .setUri(imageUrl)
                .setMimeType(MimeTypes.IMAGE_JPEG) // 이미지 타입 지정
                .build()
            setMediaItem(mediaItem)
            prepare()
        }
    }

    // ExoPlayer의 로딩 상태 관리를 통해 이미지 상태를 추적
    val playbackState by rememberUpdatedState(newValue = exoPlayer.playbackState)

    Box(
        modifier = modifier,
        contentAlignment = Alignment.Center
    ) {
        // 이미지 로딩 상태에 따른 UI 처리 (예: 로딩 중, 오류 발생 등)
        when (playbackState) {
            ExoPlayer.STATE_BUFFERING -> {
                CircularProgressIndicator() // 로딩 중일 때
            }
            ExoPlayer.STATE_READY -> {
                // 이미지 표시
                AsyncImage(
                    model = imageUrl,
                    contentDescription = null,
                    modifier = Modifier
                        .fillMaxWidth()
                        .aspectRatio(4 / 5f),
                    contentScale = ContentScale.Crop
                )
            }
            ExoPlayer.STATE_IDLE, ExoPlayer.STATE_ENDED -> {
                Text("이미지를 불러올 수 없습니다.")
            }
        }
    }

    // 화면을 벗어날 때 ExoPlayer 해제
    DisposableEffect(exoPlayer) {
        onDispose {
            exoPlayer.release()
        }
    }
}

위와 같이 이미지 로딩 상태 관리를 이용하여 네트워크 처리를 진행할 수 있다.

✅ 결론

  • ExoPlayer는 비디오 및 오디오 재생에 특화된 라이브러이기 때문에, 이미지 슬라이드 쇼와 같은 간단한 기능을 구현할 때는 불필요하게 복잡해질 수 있음.
  • Image, Video를 함께 지원하는 앱으로 변경할 때는 Video는 ExoPlayer로 Image는 Coil로 띄우는 것으로 구현해도 충분함.
  • 해리포터의 그림처럼 구현하는 JPEG 모션 사진 으로 구현할 수 있는데, 이 또한 이후의 작업을 구현할 때 다른 방법으로도 구현할 수 있는지 면밀히 확인해볼 필요가 있음.
  • 네트워크 로직 처리를 위하여 ExoPlayer를 쓰는 것도 과하다. Coil에서 ImageRequest 를 통하여 설정이 가능하기 때문에 복잡하게 ExoPlayer를 사용하지 않는 것이 옳다고 판단.

⇒ ExoPlayer는 비디오 기능을 넣을 때 추가하자!

Reference

https://stackoverflow.com/questions/50829895/how-can-i-display-image-in-exoplayer

androidx.media3:media3-exoplayer:1.4.0-rc01 부터 Image Slide를 지원한다고 함.

https://developer.android.com/media/media3/exoplayer/images?hl=ko#image-loading-libraries https://developer.android.com/media/media3/exoplayer

https://velog.io/@pass/Android-ExoPlayer-%EB%8F%99%EC%98%81%EC%83%81-%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-1-With-Compose

https://github.com/androidx/media/issues

Clone this wiki locally