ExoPlayer: 개요, 기능 및 설정

저자: IT Sectr 게시일: 2026-05-23 읽는 시간: 8 분

ExoPlayer는 Google이 내장 MediaPlayer의 대안으로 개발한 Android용 오픈소스 미디어 플레이어 라이브러리입니다. ExoPlayer는 DASH, HLS, SmoothStreaming 및 일반 미디어 파일을 포함한 다양한 형식의 오디오 및 비디오 재생을 적응형 스트리밍을 지원하는 단일 API를 통해 제공합니다. Google I/O(2024)에 따르면 ExoPlayer는 YouTube, Google TV, Netflix를 포함한 60,000개 이상의 Android 애플리케이션에서 사용됩니다.

핵심 요점

  • ExoPlayer — Google의 Android용 오픈소스 미디어 플레이어 라이브러리입니다.
  • 크로스 플랫폼 형식 — ExoPlayer는 모듈식 확장 시스템을 통해 DASH, HLS, SmoothStreaming 및 RTSP를 지원합니다.
  • 사용자 정의 — 플레이어의 모든 구성 요소(렌더러, 데이터 소스, DRM)를 자체 구현으로 교체할 수 있습니다.
  • Canvas 및 Compose — ExoPlayer는 기존 View 방식(SurfaceView)과 Jetpack Compose 모두와 통합됩니다.
  • DRM — 모듈식 DRM 시스템을 통한 Widevine, PlayReady 및 ClearKey 지원.

ExoPlayer란?

ExoPlayer는 Android용 오픈소스(Apache 2.0) 멀티미디어 재생 라이브러리로, 첫 번째 버전은 2014년 Google에서 출시했습니다. 시스템 미디어 코덱(MediaCodec)의 얇은 래퍼인 내장 MediaPlayer와 달리 ExoPlayer는 Java/Kotlin 수준에서 완전히 구현되어 개발자에게 재생의 모든 단계를 완전히 제어할 수 있는 권한을 제공합니다.

아키텍처적으로 ExoPlayer는 모듈식 원칙을 기반으로 구축되었습니다. 재생의 각 측면은 별도의 구성 요소로 구현됩니다. 핵심 모듈(exoplayer-core)에는 플레이어, 렌더러, 트랙 선택기 및 버퍼 관리가 포함됩니다. 추가 모듈(exoplayer-dash, exoplayer-hls, exoplayer-rtsp, exoplayer-smoothstreaming)은 해당 스트리밍 프로토콜에 대한 지원을 추가합니다. 이 아키텍처를 통해 애플리케이션은 필요한 구성 요소만 포함하여 APK 크기를 최소화할 수 있습니다.

ExoPlayer 2(현재 주요 버전)는 2018년에 출시되어 API의 근본적인 개편을 가져왔습니다: Player Interface 도입, AndroidX Media3를 통한 Compose 지원, 향상된 오류 처리 및 적응형 트랙 선택 알고리즘. 버전 2.19(2024)부터 ExoPlayer는 AndroidX Media 라이브러리의 일부가 되어 표준 Android 종속성 관리자를 통해 통합 및 업데이트가 간소화되었습니다.

ExoPlayer 아키텍처

ExoPlayer의 핵심에는 재생 수명 주기를 관리하는 ExoPlayerImpl 구성 요소가 있습니다. 여기에는 MediaSource(미디어 소스), TrackSelector(트랙 선택), LoadControl(버퍼링 관리) 및 Renderer 목록(비디오, 오디오, 자막 및 메타데이터용 렌더러)이 포함됩니다. 각 구성 요소는 Builder 또는 팩토리 메서드를 통해 사용자 정의 구현으로 교체할 수 있습니다.

비디오 렌더링을 위해 ExoPlayer는 SurfaceView, TextureView 또는 SphericalSurfaceView(360도 비디오용)를 사용합니다. 권장 옵션은 하드웨어 가속과 최소 전력 소비를 제공하는 SurfaceView입니다. Jetpack Compose의 경우 AndroidX Media3 라이브러리는 SurfaceView를 래핑하는 `AndroidView` 구성 요소와 기본 Compose 통합이 있는 실험적인 `Media3Compose`를 제공합니다.

ExoPlayer 기능

ExoPlayer는 일반 미디어 플레이어를 넘어 다양한 기능을 제공합니다. 주요 기능으로는 모든 인기 스트리밍 프로토콜 지원, 유연한 DRM 시스템, 적응형 비트레이트 전환(ABR) 및 재생 분석 도구가 있습니다.

기능설명모듈
DASHMPEG 표준에 따른 적응형 스트리밍exoplayer-dash
HLSApple의 HTTP Live Streamingexoplayer-hls
SmoothStreamingMicrosoft의 적응형 스트리밍exoplayer-smoothstreaming
RTSP라이브용 실시간 스트리밍 프로토콜exoplayer-rtsp
WidevineDRM 콘텐츠 보호exoplayer-drm
Concatenation여러 미디어 파일 결합exoplayer-core
Ads광고를 위한 IMA SDK 통합exoplayer-ima

적응형 비트레이트 전환

ExoPlayer의 ABR(Adaptive Bitrate)은 AdaptiveTrackSelection 인터페이스를 통해 구현됩니다. 기본적으로 네트워크 대역폭과 버퍼 크기를 고려한 균형 잡힌 알고리즘인 DefaultAdaptiveTrackSelection을 생성하는 AdaptiveTrackSelectionFactory가 사용됩니다. 특정 시나리오의 경우 BOLA(전환 최소화), RandomAdaptiveTrackSelection(테스트) 또는 TrackSelection 인터페이스를 통한 사용자 정의 구현 등의 대체 구현을 연결할 수 있습니다.

BandwidthMeter — 네트워크 대역폭 측정을 담당하는 또 다른 핵심 구성 요소입니다. 기본적으로 플레이어의 모든 HTTP 요청에 대한 통계를 수집하는 DefaultBandwidthMeter가 사용됩니다. 개발자는 네트워크 유형(Wi-Fi, 4G, 5G), 셀 타워 신호 또는 사용자 데이터 비용과 같은 추가 요소를 고려하도록 확장할 수 있습니다.

DRM 및 콘텐츠 보호

ExoPlayer는 Widevine(L1, L3), PlayReady 및 ClearKey DRM을 지원합니다. 라이선스 취득은 라이선스 서버와 상호 작용하는 DrmSessionManager를 통해 구성됩니다. 프리미엄 비디오(4K HDR)의 경우 칩 수준 보호를 제공하고 화면 캡처를 방지하는 Widevine L1의 하드웨어 지원이 필요합니다. DRM 시스템 선택은 대상 플랫폼에 따라 다릅니다: Widevine은 Android 및 Chromecast, PlayReady는 Xbox 및 Windows, FairPlay는 iOS 및 Apple TV에서 사용됩니다. ExoPlayer는 MPD 파일을 기반으로 사용 가능한 DRM 시스템을 자동으로 결정하며 기본 시나리오에서는 수동 구성이 필요하지 않습니다.

Android 프로젝트에 ExoPlayer 통합 방법

ExoPlayer를 Android 프로젝트에 연결하는 것은 Gradle 종속성을 통해 이루어집니다. 버전 2.19부터 ExoPlayer는 AndroidX Media(androidx.media3)의 일부가 되어 Jetpack Compose 및 기타 AndroidX 구성 요소와의 호환성을 보장합니다. Kotlin에서 단계별 통합을 살펴보겠습니다.

종속성 추가

build.gradle 파일(Module)에 ExoPlayer 모듈을 추가합니다. 최소 세트에는 core, ui 및 필요한 스트리밍 프로토콜용 모듈이 포함됩니다. DASH 콘텐츠 재생에는 exoplayer-dash, HLS에는 exoplayer-hls가 필요합니다.

groovy
dependencies {
    implementation "androidx.media3:media3-exoplayer:1.5.0"
    implementation "androidx.media3:media3-ui:1.5.0"
    implementation "androidx.media3:media3-exoplayer-dash:1.5.0"
    implementation "androidx.media3:media3-exoplayer-hls:1.5.0"
}

Activity에서 기본 통합

Activity 또는 Fragment에서 플레이어 생성 및 구성. ExoPlayer는 비디오 및 내장 컨트롤을 표시하기 위해 PlayerView(또는 사용자 정의를 위한 StyledPlayerView)를 사용합니다. 최소 구성에는 ExoPlayer.Builder를 통한 플레이어 생성과 소스 URI가 포함된 MediaItem 전달이 포함됩니다.

kotlin
class PlayerActivity : AppCompatActivity() {

    private var player: ExoPlayer? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_player)

        player = ExoPlayer.Builder(this).build()
        val playerView = findViewById<StyledPlayerView>(R.id.playerView)
        playerView.player = player

        val mediaItem = MediaItem
            .Builder()
            .setUri("https://example.com/video.mp4")
            .build()
        player?.setMediaItem(mediaItem)
        player?.prepare()
    }

    override fun onDestroy() {
        player?.release()
        super.onDestroy()
    }
}

오류 처리 및 상태

프로덕션 애플리케이션의 경우 네트워크 오류, 지원되지 않는 형식, DRM 라이선싱 오류 등 가능한 재생 오류 처리가 필요합니다. ExoPlayer는 onPlayerError, onPlaybackStateChanged 및 onPlayWhenReadyChanged 메서드가 있는 Player.Listener 인터페이스를 제공합니다. 사용자에게 재시도 옵션과 함께 정보성 오류 메시지를 표시하는 것이 좋습니다.

ExoPlayer vs MediaPlayer: 비교

ExoPlayer와 내장 MediaPlayer 중 선택은 Android 애플리케이션 개발 시 일반적인 질문입니다. MediaPlayer는 버전 1.0부터 Android SDK의 일부인 반면, ExoPlayer는 Gradle 종속성이 필요한 라이브러리입니다. 주요 기준에 따른 차이점을 살펴보겠습니다.

기준ExoPlayerMediaPlayer
아키텍처모듈식, 완전히 Java/Kotlin시스템 C++ 구성 요소의 래퍼
스트리밍DASH, HLS, SmoothStreaming, RTSP로컬 파일 및 HLS만(Android 9+)
사용자 정의전체(모든 구성 요소 교체 가능)최소(매개변수만)
업데이트Google Play 또는 APK를 통해(OS 독립적)Android 업데이트(OTA)를 통해서만
APK 크기+1–3MB(모듈에 따라 다름)0(OS의 일부)
최소 SDKAPI 16+(Android 4.1)API 1+
DRMWidevine, PlayReady, ClearKeyWidevine(제한적)

ExoPlayer가 우수한 경우는 스트리밍(DASH, HLS), UI 사용자 정의, DRM 지원 및 Android 버전 독립성이 필요한 시나리오입니다. MediaPlayer는 APK 크기가 중요하고 적응형 스트리밍 요구 사항이 없는 로컬 미디어 파일을 재생하는 간단한 애플리케이션에 적합합니다. 네트워크 콘텐츠가 있는 최신 애플리케이션의 경우 ExoPlayer가 명확한 선택입니다.

예외 — 최소 SDK가 API 16(Android 4.1) 미만인 애플리케이션은 시장에 거의 존재하지 않습니다. targetSdk 33+ 및 최소 SDK 21+가 있는 모든 애플리케이션의 경우 ExoPlayer는 선호될 뿐만 아니라 적절한 확장을 통해 AV1 및 Dolby Vision과 같은 최신 형식을 지원하는 데 필요합니다.

ExoPlayer 고급 설정

프로덕션 애플리케이션의 경우 ExoPlayer 기본 통합에는 종종 추가 구성이 필요합니다: 캐시 관리, 모바일 네트워크용 버퍼 최적화, 분석 통합 및 오디오 트랙 선택 사용자 정의. 고급 사용 시나리오를 살펴보겠습니다.

콘텐츠 캐싱

CacheDataSourceFactory를 사용하면 다운로드한 세그먼트를 로컬 저장소에 캐시하여 반복 시청 시 트래픽을 절약하고 오프라인 재생을 가능하게 합니다. ExoPlayer는 exoplayer-cas 라이브러리의 SimpleCache — LRU 제거 지원 및 크기 제한이 있는 파일 기반 캐싱을 사용합니다.

kotlin
val cache = SimpleCache(
    cacheDir,
    LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024),
    AppDatabaseProvider(this)
)

val cacheDataSourceFactory = CacheDataSource
    .Factory()
    .setCache(cache)

val player = ExoPlayer.Builder(this)
    .setMediaSourceFactory(
        DefaultMediaSourceFactory(cacheDataSourceFactory)
    )
    .build()

네트워크 전환 처리

모바일 애플리케이션에서 Wi-Fi와 셀룰러 네트워크 간 전환 처리는 중요합니다. ExoPlayer는 네트워크 상태 추적을 위한 ConnectivityManager를 제공합니다. 연결이 끊어지면 플레이어를 중지하지 않고 위치를 유지하면서 PAUSED 상태로 전환하는 것이 좋습니다. 연결이 복원된 후 세그먼트를 다시 로드하여 재생을 재개합니다.

Jetpack Compose 통합

AndroidX Media3 출시와 함께 라이브러리는 Jetpack Compose에 대한 실험적 지원을 받았습니다. `AndroidView` 구성 요소는 SurfaceView 또는 PlayerView를 래핑하여 Compose 계층 구조와의 호환성을 보장합니다. 더 깊은 통합을 위해 Compose 호환 플레이어 컨트롤을 제공하는 `androidx.media3:media3-ui-compose` 라이브러리가 사용됩니다.

kotlin
@Composable
fun VideoPlayer(uri: String) {
    val context = LocalContext.current
    val player = remember {
        ExoPlayer.Builder(context).build()
            .also { it.setMediaItem(MediaItem.fromUri(uri)) }
    }

    DisposableEffect(key = null) {
        player.prepare()
        onDispose { player.release() }
    }

    AndroidView(
        factory = { StyledPlayerView(context).also { it.player = player } }
    )
}

자주 묻는 질문

ExoPlayer에 필요한 최소 Android 버전은?

ExoPlayer는 Android API 16+(Android 4.1 Jelly Bean)을 지원합니다. 그러나 fMP4 세그먼트가 있는 DASH 및 HLS의 경우 API 21+(Android 5.0 Lollipop)이 권장됩니다. DRM 모듈(Widevine)은 API 19+가 필요하고 하드웨어 HEVC 디코딩은 API 21부터 사용할 수 있습니다.

ExoPlayer를 비디오 없이 오디오 전용으로 사용할 수 있나요?

네, ExoPlayer는 오디오에 탁월합니다. 오디오 전용 재생에는 SurfaceView나 PlayerView가 필요하지 않습니다. ExoPlayer가 자동으로 오디오 렌더러를 선택하고 백그라운드에서 작동합니다. 백그라운드 재생의 경우 시스템 컨트롤과의 통합을 위해 MediaSessionService를 사용하는 것이 좋습니다.

ExoPlayer에서 오디오 트랙을 전환하려면?

ExoPlayer의 TrackSelector가 오디오 트랙 선택을 관리합니다. 전환하려면 기본 오디오 언어를 지정하여 player.getCurrentTracks().groups 및 player.setTrackSelectionParameters()를 사용하세요. 여러 오디오 트랙이 있는 DASH 및 HLS 스트림의 경우 재생 중단 없이 전환됩니다.

ExoPlayer가 자막을 지원하나요?

네, ExoPlayer는 내장(MP4, WebM 컨테이너) 및 외부 자막을 TTML, SRT, VTT 및 CEA-608 형식으로 지원합니다. 외부 자막의 경우 비디오 스트림과 병합하기 위해 SingleSampleMediaSource 또는 MergingMediaSource가 사용됩니다. 스타일 자막 표시는 CaptionStyleCompat을 통해 구성됩니다.

ExoPlayer 라이브 스트리밍에서 지연 시간을 줄이려면?

저지연 스트리밍의 경우 더 작은 목표 버퍼 값으로 LoadControl을 구성하세요: HLS LL 및 DASH LL의 경우 DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000)을 사용합니다. 또한 라이브 방송보다 느릴 때 가속 버퍼 채우기를 위해 minPlaybackSpeed = 1.02를 설정합니다.

요약

  • ExoPlayer — 모듈식 아키텍처와 완전한 사용자 정의를 갖춘 Google의 오픈소스 미디어 플레이어 라이브러리.
  • 적응형 스트리밍 — 모듈식 확장 시스템을 통해 DASH, HLS, SmoothStreaming 및 RTSP 지원.
  • DRM — Widevine, PlayReady 및 ClearKey가 통합 API로 exoplayer-drm 모듈을 통해 통합.
  • 캐싱 — SimpleCache로 오프라인 재생 가능 및 반복 시청 시 트래픽 절약.
  • Compose — AndroidX Media3부터 ExoPlayer가 AndroidView를 통해 Jetpack Compose와 통합.
  • 사용자 정의 — 모든 구성 요소(MediaSource, TrackSelector, LoadControl, Renderer) 교체 가능.
  • 권장 스트리밍, DRM 또는 재생 사용자 정의가 필요한 모든 프로젝트에 ExoPlayer 사용.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기