Skip to content

fix: 트랙 교체 시 RTMP egress가 중단되어 송출이 단절됨 #84

Description

@itzjb

현상

발행자가 방송 중 카메라를 전환하면(트랙 교체) RTMP 송출이 중단되고 재연결된다. 시청자 쪽에서는 스트림이 끊겼다가 다시 붙는 것으로 보인다.

원인

egress의 수명이 세션이 아니라 트랙에 묶여 있다.

  • internal/session/manager.go:493 — 트랙마다 trackCtx를 새로 만든다
  • internal/session/manager.go:531go egress.Run(trackCtx) 로 egress를 그 컨텍스트에 묶는다
  • internal/session/manager.go:486-491 — 새 트랙이 도착하면 기존 s.trackCancel() 을 호출해 이전 컨텍스트를 취소한다

따라서 트랙이 교체되는 순간 egress가 종료된다. 현재는 새 트랙의 OnTrack 콜백이 egress를 새로 생성하기 때문에 결과적으로 복구되지만, 그 사이 RTMP 연결이 끊기고 FFmpeg가 재기동되므로 송출이 단절된다.

현재 이 결함이 드러나지 않는 이유

YOUTUBE_STREAM_KEY 가 2026-08-02 시크릿 재작성 과정에서 유실된 뒤 복구되지 않았다. manager.go:526 이 키가 비면 egress 생성 자체를 건너뛰므로, 현재 프로덕션에서는 RTMP 송출 경로가 동작하지 않는다. 키가 있던 시점에는 실제로 발생하던 결함이다.

수정 방향

egress 수명을 세션 수명으로 옮긴다.

  • egress 생성을 OnTrack 콜백 밖으로 이동
  • 세션 수명 컨텍스트 + egress 전용 cancel 을 둔다 (세션은 유지한 채 egress만 종료할 수 있어야 한다 — 현 구조에 없는 개념)
  • Session 에 egress 참조를 보관하고, 트랙 교체 시 새 RunTrack 호출에 기존 egress를 재전달한다
  • StreamState 갱신 골격을 함께 넣는다. 상태 전이가 egress 수명 이벤트에서 발생하므로 분리하면 같은 코드를 두 번 열게 된다

media 패키지는 손대지 않아도 된다. egress.Run 은 입력 채널 기반이라 프레임 공급자(파이프라인)가 교체돼도 Enqueue 만 이어지면 생존한다(internal/media/track.go:351-352).

함께 정의해야 하는 것

egress가 세션 수명으로 바뀌면, 트랙 교체로 해상도가 바뀌는 경우의 처리가 새로 필요하다. 현행은 egress가 죽고 재생성되면서 collectStartupFrames 가 새 해상도를 다시 측정했으나, 수명을 분리하면 그 재측정 지점이 사라진다. FFmpeg 재기동 조건을 이 작업에서 정의한다.

범위 제한 (중요)

이 이슈는 동작 보존 + 연속성 수정까지다.

  • egress 생성 트리거는 현행 그대로 전역 YOUTUBE_STREAM_KEY 를 유지한다
  • 사용자별 송출 로직을 한 줄도 넣지 않는다
  • handleStartStream / handleStopStream 실배선도 포함하지 않는다 (start 없는 stop은 계약상 반쪽이며, 이 이슈를 "동작 보존"으로 유지하는 것이 리뷰 가치의 핵심)

위 항목들은 전부 #83 에서 처리한다.

검증

internal/session 은 고루틴·atomic·mutex가 밀집한 코드이므로 make test-race 필수. TestBypassWebRTCEndToEnd 는 병렬 실행 시 가끔 실패하는 알려진 flaky이므로 격리 실행으로 확인한다.

관계

#83 (사용자별 RTMP 송출 대상 도입)의 선행 작업. #83 이 요구하는 "명시적 방송 시작" 구조가 성립하려면 egress가 트랙보다 오래 살아야 한다.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions