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