RTSP

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

지원되는 샘플 형식

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

지원되는 네트워크 유형

  • UDP unicast를 통한 RTP (멀티캐스트는 지원되지 않음)
  • 인터리빙된 RTSP, TCP를 사용한 RTSP를 통한 RTP

MediaItem 사용

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

Kotlin

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

Groovy

implementation "androidx.media3:media3-exoplayer-rtsp:1.4.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()

자바

// 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 사용

더 많은 맞춤설정 옵션을 사용하려면 MediaItem 대신 RtspMediaSource를 만들어 재생기에 직접 전달하면 됩니다.

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()

자바

// 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는 Java의 표준 소켓 팩토리(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));