RTSP

ExoPlayer는 실시간 및 주문형 RTSP를 모두 지원합니다. 지원되는 샘플 형식과 네트워크 유형은 다음과 같습니다.

지원되는 샘플 형식

  • H264 (SDP 미디어 설명은 디코더 초기화를 위한 fmtp 속성에 SPS/PPS 데이터를 포함해야 함)
  • AAC (ADS 비트스트림 포함)
  • AC3입니다.

지원되는 네트워크 유형

  • RTP over UDP 유니캐스트 (멀티캐스트는 지원되지 않음)
  • 인터리브 처리된 RTSP, TCP를 사용하는 RTSP를 통한 RTP

MediaItem 사용

RTSP 스트림을 재생하려면 RTSP 모듈을 사용해야 합니다.

Kotlin

implementation("androidx.media3:media3-exoplayer-rtsp:1.3.1")

Groovy

implementation "androidx.media3:media3-exoplayer-rtsp:1.3.1"

그런 다음 RTSP URI의 MediaItem를 만들어 플레이어에 전달할 수 있습니다.

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(rtspUri))
// Prepare the player.
player.prepare()

Java

// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(rtspUri));
// Prepare the player.
player.prepare();

인증

ExoPlayer는 RTSP BASIC 및 DIGEST 인증으로 재생을 지원합니다. 보호된 RTSP 콘텐츠를 재생하려면 MediaItem의 URI를 인증 정보로 구성해야 합니다. 구체적으로 URI는 rtsp://<username>:<password>@<host address> 형식이어야 합니다.

RtspMediaSource 사용

더 많은 맞춤설정 옵션을 위해 RtspMediaSource를 만들어 MediaItem 대신 플레이어에 직접 전달하면 됩니다.

Kotlin

// Create an RTSP media source pointing to an RTSP uri.
val mediaSource: MediaSource =
RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri))
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media source to be played.
player.setMediaSource(mediaSource)
// Prepare the player.
player.prepare()

Java

// Create an RTSP media source pointing to an RTSP uri.
MediaSource mediaSource =
    new RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();

NAT 뒤에서 RTSP 사용 (RTP/TCP 지원)

ExoPlayer는 RTP 전송을 위한 기본 프로토콜로 UDP를 사용합니다.

NAT 레이어 뒤에서 RTSP를 스트리밍할 때 NAT는 수신 RTP/UDP 패킷을 기기로 전달하지 못할 수 있습니다. 이는 NAT에 필요한 UDP 포트 매핑이 없는 경우에 발생합니다. ExoPlayer가 한동안 수신되는 RTP 패킷이 없고 재생이 아직 시작되지 않은 경우 ExoPlayer는 현재 RTSP 재생 세션을 해체하고 RTP-over-RTSP(RTSP에 열린 TCP 연결을 사용하여 RTP 패킷을 전송)를 사용하여 재생을 다시 시도합니다.

TCP로 재시도하는 제한 시간은 RtspMediaSource.Factory.setTimeoutMs() 메서드를 호출하여 맞춤설정할 수 있습니다. 예를 들어 제한 시간을 4초로 설정하면 플레이어는 UDP가 비활성 상태로 4초가 지나면 TCP로 다시 시도합니다.

제한 시간 설정은 스트림 종료 감지 로직에도 영향을 줍니다. 즉, ExoPlayer는 설정된 제한 시간 동안 아무것도 수신되지 않으면 재생이 종료되었다고 보고합니다. 이 값을 너무 작게 설정하면 네트워크 상태가 좋지 않을 때 스트림의 조기 종료 신호가 발생할 수 있습니다.

RTP/TCP는 일부 네트워크 설정에서 더 나은 호환성을 제공합니다. RtspMediaSource.Factory.setForceUseRtpTcp()를 사용하여 기본적으로 RTP/TCP를 사용하도록 ExoPlayer를 구성할 수 있습니다.

맞춤 SocketFactory 전달

커스텀 SocketFactory 인스턴스는 특정 라우팅이 필요한 경우에 유용할 수 있습니다 (예: RTSP 트래픽이 특정 인터페이스를 전달해야 하거나 소켓에 추가 연결 플래그가 필요한 경우).

기본적으로 RtspMediaSource는 자바의 표준 소켓 팩토리(SocketFactory.getDefault())를 사용하여 원격 엔드포인트에 대한 연결을 만듭니다. 이 동작은 RtspMediaSource.Factory.setSocketFactory()를 사용하여 재정의할 수 있습니다.

Kotlin

// Create an RTSP media source pointing to an RTSP uri and override the socket
// factory.
val mediaSource: MediaSource =
RtspMediaSource.Factory()
    .setSocketFactory(...)
    .createMediaSource(MediaItem.fromUri(rtspUri))

Java

// Create an RTSP media source pointing to an RTSP uri and override the socket
// factory.
MediaSource mediaSource =
    new RtspMediaSource.Factory()
        .setSocketFactory(...)
        .createMediaSource(MediaItem.fromUri(rtspUri));