방송이 잠시 끊겼을 때 시청 화면을 유지하는 대체 영상은 유용합니다. 하지만 그 화면까지 원본 녹화에 계속 쌓이면, 편집용 기록에는 실제 방송이 아닌 구간이 포함됩니다. “시청 가능한 경로가 있다”와 “실제 방송 소스가 온라인이다”는 같은 상태가 아니었습니다.

MediaMTX에는 이미 AbdElrahmaN31의 PR #5767이 이 선택지를 제안하고 있었습니다. 저는 원 작성자의 커밋을 보존해 PR #6182로 이어갔습니다. 같은 3개 시나리오를 대조하니 원 기여에서는 publisher 경로만 통과했고, static source와 오프라인 reload에는 빈틈이 있었습니다. 녹화 수명을 공통 온라인 상태에 맞춰 세 경로 모두 통과하게 보완한 부분이 제 기여입니다. 구현·검증은 AI와 협업했습니다.

이 PR은 2026년 9월 5일 병합돼 v1.21.0 정식 릴리스에 반영됐습니다.

원 기여가 해결한 경로와 남은 경로를 나눴다

alwaysAvailable은 실제 소스가 오프라인이어도 대체 화면을 제공할 수 있게 합니다. record가 켜져 있으면 그 대체 화면도 녹화되는 기존 동작이 있었습니다. 원 기여는 alwaysAvailableRecorded 설정으로 이를 끌 수 있게 하는 출발점이었습니다.

그러나 publisher가 연결되는 경로에서 녹화 시작을 처리하는 것만으로는 충분하지 않았습니다. MediaMTX는 외부 publisher뿐 아니라 설정된 static source가 온라인이 되는 경로도 갖습니다. 이 경로에서는 publisher 추가 함수만 거치지 않으므로 녹화 시작이 누락됐습니다.

설정 reload에는 다른 빈틈이 있었습니다. pa.source != nil을 온라인 판정으로 사용하면 실제로 연결되지 않은 static source 객체나 대체 소스의 존재를 실제 방송으로 해석할 수 있습니다. 오프라인 상태에서 설정을 다시 읽었을 뿐인데 대체 화면의 녹화가 시작되는 이유였습니다.

같은 회귀 시나리오 원 기여 커밋만 적용 보완 뒤
publisher가 온라인이 됨 정상 통과
static source가 온라인이 됨 녹화 시작 누락 통과
오프라인 상태에서 reload 대체 화면 녹화 시작 통과

두 실패는 방향도 반대였습니다. static source에서는 녹화해야 할 때 시작하지 않았고, 오프라인 reload에서는 녹화하지 말아야 할 때 시작했습니다. 각각의 함수에 조건을 추가하기 전에 두 경로가 무엇을 온라인이라고 판단하는지부터 맞춰야 했습니다.

녹화의 기준을 진입 함수에서 상태 전환으로 옮겼다

수정은 녹화 시작·종료를 setOnline()과 setOffline()에 연결하는 방향입니다. publisher와 static source가 모두 통과하는 상태 전환에서 처리하면 입력 방식이 달라도 같은 녹화 규칙을 따를 수 있습니다. reload 역시 source 포인터가 있는지보다 isOnline()을 확인하도록 바꿨습니다.

이를 통해 시청용 대체 화면을 제공하는 책임과 실제 원본을 녹화하는 책임을 분리했습니다. 소스가 끊겨도 대체 화면은 계속 제공할 수 있지만, 사용자가 해당 옵션을 끄면 오프라인 구간은 녹화하지 않습니다. 두 기능을 동시에 켜거나 끄는 것으로 문제를 단순화하지 않았습니다.

저는 publisher 경로에 있는 조건을 static source 쪽에 복사하는 대신, 두 입력이 공통으로 통과하는 상태 전환을 수정 지점으로 택했습니다. 옵션의 의미는 소스 종류에 따라 달라지는 것이 아니라 실제 방송이 온라인인 동안만 녹화하는 것이기 때문입니다. reload도 같은 상태를 읽어야 이 규칙을 우회하지 않습니다.

기본값과 설정 인터페이스도 변경 범위였다

alwaysAvailableRecorded의 기본값은 true로 유지했습니다. 기존 사용자는 설정을 바꾸지 않으면 대체 화면을 녹화하던 동작을 그대로 얻습니다. false를 선택한 경우에만 실제 소스가 온라인인 동안 녹화합니다.

설정 동작
기본값 true 기존 녹화 동작 유지
명시적 false 실제 소스가 온라인일 때만 녹화
시청 경로 대체 화면 제공과 별도로 동작

새 옵션은 런타임 코드 안에만 있으면 충분하지 않습니다. mediamtx.yml의 설명과 생성된 OpenAPI 정의도 맞췄습니다. 파일 설정으로 보이는 이름과 API가 받는 계약이 달라지지 않게 한 것입니다. 이 작업의 공개 변경 범위는 PR의 파일 목록에서 확인할 수 있습니다.

재로드 중의 상태도 회귀 검증에 넣었다

재현 조건은 alwaysAvailable 활성화, alwaysAvailableRecorded: false, record 활성화, H264 트랙 1개였습니다. 앞의 1/3→3/3 통과는 이 조건에서 같은 세 테스트를 원 기여와 보완 상태에 적용한 결과입니다. publisher의 정상 경로를 유지하면서 static source의 시작 누락과 오프라인 reload의 불필요한 녹화를 함께 막았는지 확인했습니다. 다른 소스·코덱·장애 조합은 이 세 테스트의 범위를 벗어납니다.

v1.21.0 사용자는 기본값 true로 기존 녹화 동작을 유지하거나, false로 대체 화면을 보여주면서 실제 소스만 녹화할 수 있습니다. 이 하나의 선택이 입력 방식과 reload에 따라 바뀌지 않게 만드는 것이 보완의 목표였습니다. 기존 기여의 아이디어와 커밋을 이어받고, 제가 확인한 두 상태 경계를 같은 규칙 안으로 넣어 완성한 변경입니다.


이 글은 PokeClip·MediaMTX 기술 기록 모음의 일부입니다. 포트폴리오 전체본 40쪽에서 연결된 사례도 함께 볼 수 있습니다.