203 lines
9.9 KiB
Markdown
203 lines
9.9 KiB
Markdown
# RTSP
|
|
|
|
Windows의 활성 모니터를 독립 RTSP 채널로 송출하고, 실제 재생 신호가 있는 오디오 출력 장치를 자동 선택해 시스템 소리를 함께 전송하는 PowerShell 기반 watchdog입니다.
|
|
|
|
## 프로젝트 성격
|
|
|
|
RTSP는 `ddagrab` 기반 Desktop Duplication API로 화면과 마우스 커서를 캡처하고, 사용 가능한 GPU 하드웨어 인코더를 실제 초기화 시험한 뒤 FFmpeg와 MediaMTX를 관리합니다.
|
|
|
|
특정 노트북의 NIC 이름이나 `ifIndex`에 고정되지 않는 범용 구성이 기본입니다. 필요한 환경에서는 `-NicDescription`과 `-HealthTarget`을 함께 지정해 특정 NIC의 Link, IPv4, Source IP 통신까지 송출 조건으로 강제할 수 있습니다.
|
|
|
|
## 주요 기능
|
|
|
|
- Windows PowerShell 5.1 지원
|
|
- 활성 모니터별 독립 RTSP 채널 제공
|
|
- Desktop Duplication API `ddagrab` 화면 캡처
|
|
- 전체 화면과 마우스 커서 포함
|
|
- 모니터 연결, 해제, 좌표, 해상도, 회전, Primary 변경 감지
|
|
- NVIDIA NVENC, AMD AMF, Intel QSV 자동 감지
|
|
- GPU 존재 여부와 FFmpeg 1프레임 초기화 시험을 함께 사용한 인코더 선택
|
|
- 기본 우선순위 `NVIDIA > AMD > Intel`, 실행 인자로 변경 가능
|
|
- Windows Core Audio WASAPI loopback 기반 시스템 재생음 캡처
|
|
- 실제 오디오 peak가 있는 출력 장치 우선 선택
|
|
- 무음 상태에서는 기본 출력 장치를 유지해 송출이 불필요하게 끊기지 않음
|
|
- 기본 출력 장치, 재생 장치, 오디오 포맷 변경 시 전체 채널 재시작
|
|
- 기본 30fps, 영상 8Mbps, AAC 오디오 192kbps
|
|
- NIC Link, IPv4, `ifIndex`, IP 변경 감지
|
|
- 선택적 Source IP 고정 ping 상태 검사
|
|
- 3초간 정상 상태가 유지된 뒤 전체 채널 시작
|
|
- FFmpeg 또는 오디오 worker 하나가 종료되면 전체 채널 재시작
|
|
- MediaMTX 종료 시 자동 재시작
|
|
- 기존 MediaMTX가 RTSP 포트를 사용 중이면 해당 프로세스 재사용
|
|
- 자동 생성 MediaMTX 설정은 RTSP over TCP만 사용해 UDP RTP 포트 충돌 방지
|
|
- 로그인 시 자동 실행 작업 등록 및 제거
|
|
- `config.ini` 기반 기능별 설정과 명령줄 override
|
|
- 오디오 캡처/AAC 트랙을 `1` 또는 `0`으로 활성화·비활성화
|
|
|
|
## RTSP URL
|
|
|
|
기본 2채널 구성은 다음 URL을 유지합니다.
|
|
|
|
```text
|
|
rtsp://<현재_NIC_IP>:8554/monitor1
|
|
rtsp://<현재_NIC_IP>:8554/monitor2
|
|
```
|
|
|
|
## 구성
|
|
|
|
- `screen-rtsp.ps1`: 캡처, 오디오 loopback, GPU 선택, MediaMTX/FFmpeg watchdog
|
|
- `config.ini`: 영상, 오디오, 네트워크, RTSP 설정과 진단 명령 예시
|
|
- `ffmpeg.exe`: `ddagrab`, `h264_nvenc`, `h264_amf`, `h264_qsv`, `aac` 지원 FFmpeg
|
|
- `mediamtx.exe`: RTSP 서버. 현재 검증 기준 버전은 v1.21.1
|
|
- `mediamtx.yml`: 없으면 스크립트가 기본 설정을 자동 생성
|
|
- `logs/watchdog.log`: watchdog 상태 로그
|
|
- `logs/monitor1-ffmpeg.log`: monitor1 FFmpeg 로그
|
|
- `logs/monitor2-ffmpeg.log`: monitor2 FFmpeg 로그
|
|
- `logs/monitor1-audio.log`, `logs/monitor2-audio.log`: WASAPI loopback worker 오류 로그
|
|
|
|
실행 파일과 생성 파일은 저장소에 포함하지 않습니다. 배포할 때 `ffmpeg.exe`와 `mediamtx.exe`를 `screen-rtsp.ps1` 옆에 둡니다.
|
|
|
|
## 설정 파일
|
|
|
|
기본 설정은 `screen-rtsp.ps1`과 같은 폴더의 `config.ini`에서 읽습니다.
|
|
|
|
```ini
|
|
[Video]
|
|
FrameRate=30
|
|
Bitrate=8000k
|
|
EncoderPriority=NVIDIA,AMD,Intel
|
|
|
|
[Audio]
|
|
Enabled=1
|
|
Bitrate=192k
|
|
SignalThreshold=0.0005
|
|
```
|
|
|
|
`Audio.Enabled=1`이면 현재 재생 장치의 시스템 소리를 WASAPI loopback으로 캡처해 AAC 트랙을 추가합니다. `0`이면 오디오 장치 감시, loopback worker, AAC 트랙을 모두 사용하지 않고 영상만 송출합니다.
|
|
|
|
줄 앞의 공백을 제외한 첫 문자가 `#`, `;`, `//`이면 설명이나 참고 명령으로 인식해 건너뜁니다. 값 오른쪽의 inline 주석은 지원하지 않으므로 설명은 별도 줄에 작성합니다. 명령줄에서 직접 지정한 값은 INI 값보다 우선합니다.
|
|
|
|
알 수 없는 섹션, 설정 이름, 범위를 벗어난 값, `0/1` 이외의 기능 스위치는 시작 전에 오류로 표시합니다.
|
|
|
|
| 섹션 | 설정 | 기본값 | 설명 |
|
|
|---|---|---:|---|
|
|
| `General` | `ChannelCount` | `2` | 송출 채널과 필요한 모니터 수 |
|
|
| `General` | `StableTimeSec` | `3` | 정상 상태 안정화 시간 |
|
|
| `General` | `PollIntervalSec` | `1` | 상태 확인 주기 |
|
|
| `Video` | `FrameRate` | `30` | 화면 프레임률 |
|
|
| `Video` | `Bitrate` | `8000k` | 채널별 영상 비트레이트 |
|
|
| `Video` | `EncoderPriority` | `NVIDIA,AMD,Intel` | GPU 선택 순서 |
|
|
| `Audio` | `Enabled` | `1` | 시스템 재생음과 AAC 트랙 사용 여부 |
|
|
| `Audio` | `Bitrate` | `192k` | AAC 비트레이트 |
|
|
| `Audio` | `SignalThreshold` | `0.0005` | 실제 재생 장치 판별 peak 기준 |
|
|
| `Network` | `NicDescription` | 빈 값 | 비우면 기본 경로 NIC 자동 선택 |
|
|
| `Network` | `HealthTarget` | 빈 값 | Source IP ping 대상 |
|
|
| `RTSP` | `Port` | `8554` | MediaMTX RTSP 포트 |
|
|
|
|
GPU, 모니터, 오디오, NIC, FFmpeg 지원, RTSP 포트를 확인하는 PowerShell 명령은 `config.ini` 위쪽에 모두 주석 형태로 포함되어 있습니다.
|
|
|
|
INI를 해석한 최종 설정값만 확인하고 종료할 수도 있습니다.
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 -ShowConfiguration
|
|
```
|
|
|
|
## 처리 흐름
|
|
|
|
1. FFmpeg의 `ddagrab`과 H.264 하드웨어 인코더 포함 여부를 확인합니다.
|
|
2. 설치된 GPU를 `NVIDIA > AMD > Intel` 순서로 찾고 각 인코더를 실제 1프레임으로 초기화합니다.
|
|
3. 활성 모니터, IPv4 기본 경로 NIC, 활성 오디오 출력 장치를 읽습니다.
|
|
4. Core Audio peak가 감지된 출력 장치를 우선하고, 신호가 없으면 Windows 기본 출력 장치를 사용합니다.
|
|
5. 모든 조건이 3초 동안 유지되면 채널마다 WASAPI loopback worker와 FFmpeg를 시작합니다.
|
|
6. 화면은 `ddagrab -> hwdownload -> BGRA -> 회전 보정 -> NV12 -> 하드웨어 H.264` 순서로 처리합니다.
|
|
7. 시스템 소리는 named pipe를 통해 FFmpeg로 전달하고 AAC로 인코딩합니다.
|
|
8. 모니터, NIC, GPU, 오디오 장치 또는 자식 프로세스 상태가 바뀌면 전체 채널을 종료한 뒤 새 구성을 읽어 재시작합니다.
|
|
|
|
## 설치 및 실행
|
|
|
|
관리자 PowerShell에서 실행 정책을 우회해 시작합니다.
|
|
|
|
```powershell
|
|
Set-Location C:\RTSP
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\screen-rtsp.ps1
|
|
```
|
|
|
|
로그인 자동 실행은 대화형 사용자 세션에 예약 작업을 등록합니다. Desktop Duplication과 사용자 재생 오디오를 캡처해야 하므로 Windows 서비스가 아니라 로그인 트리거를 사용합니다.
|
|
|
|
```powershell
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\screen-rtsp.ps1 -InstallStartup
|
|
```
|
|
|
|
등록된 작업은 `config.ini` 경로만 전달하므로 설정 파일을 수정한 뒤 작업을 다시 시작하면 변경값이 적용됩니다.
|
|
|
|
```powershell
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\screen-rtsp.ps1 -StartupStatus
|
|
Stop-ScheduledTask -TaskName "Screen RTSP Watchdog"
|
|
Start-ScheduledTask -TaskName "Screen RTSP Watchdog"
|
|
```
|
|
|
|
자동 실행 제거:
|
|
|
|
```powershell
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\screen-rtsp.ps1 -UninstallStartup
|
|
```
|
|
|
|
## 실행 옵션
|
|
|
|
다른 설정 파일을 사용하는 예시:
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 -ConfigPath C:\RTSP\config.ini
|
|
```
|
|
|
|
명령줄 값은 `config.ini`보다 우선합니다. 다음 실행에서만 오디오를 끄는 예시:
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 -AudioEnabled 0
|
|
```
|
|
|
|
GPU 우선순위를 바꾸는 예시:
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 -EncoderPriority Intel,NVIDIA,AMD
|
|
```
|
|
|
|
채널 수와 영상 설정을 바꾸는 예시:
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 -ChannelCount 2 -FrameRate 30 -VideoBitrate 8000k -AudioBitrate 192k
|
|
```
|
|
|
|
특정 ASIX NIC와 Gateway 통신을 필수 조건으로 사용하는 노트북 예시:
|
|
|
|
```powershell
|
|
.\screen-rtsp.ps1 `
|
|
-NicDescription "ASIX USB to Gigabit Ethernet Family Adapter" `
|
|
-HealthTarget "192.168.50.1"
|
|
```
|
|
|
|
이 모드에서도 NIC 이름이나 `ifIndex`가 아니라 `InterfaceDescription`으로 매번 다시 검색합니다. Source IP ping은 검색된 NIC의 현재 IPv4를 사용합니다.
|
|
|
|
## 오디오 장치 선택 정책
|
|
|
|
스크립트는 활성 상태의 Windows Render endpoint를 모두 읽고 각 장치의 peak를 확인합니다.
|
|
|
|
- 현재 선택 장치에 실제 신호가 계속 있으면 해당 장치를 유지합니다.
|
|
- 다른 활성 장치에서만 신호가 감지되면 해당 장치로 전환합니다.
|
|
- 모든 장치가 무음이면 Windows 기본 Multimedia 출력 장치를 선택합니다.
|
|
- 선택 장치가 제거되거나 기본 장치와 mix format이 바뀌면 전체 RTSP 채널을 재시작합니다.
|
|
|
|
이 정책은 음악이나 알림 사이의 무음 구간마다 송출이 중단되는 것을 막으면서, Bluetooth/HDMI/USB 오디오처럼 실제 재생 장치가 바뀌는 상황을 자동 반영합니다.
|
|
|
|
## 운영 체크포인트
|
|
|
|
- `ddagrab`은 대화형 데스크톱 세션이 필요합니다. 사용자가 로그인하지 않은 부팅 직후 세션에서는 화면과 사용자 오디오를 캡처할 수 없습니다.
|
|
- GPU 이름만으로 인코더를 확정하지 않습니다. 드라이버 또는 세션 문제로 초기화가 실패하면 다음 우선순위 GPU를 시험합니다.
|
|
- 여러 GPU에 모니터가 물린 특수 구성에서는 FFmpeg가 사용하는 D3D11 adapter의 출력 순서를 확인해야 합니다.
|
|
- RTSP 포트를 MediaMTX가 아닌 다른 프로세스가 사용하면 충돌 프로세스를 종료하지 않고 송출을 대기합니다.
|
|
- 인증이 없는 기본 MediaMTX 설정은 신뢰된 LAN에서만 사용하고, 외부 네트워크에 노출할 때는 MediaMTX 인증과 방화벽 정책을 추가합니다.
|
|
|
|
## 저장소 정책
|
|
|
|
FFmpeg와 MediaMTX 바이너리, 로그, 자동 생성 설정, 인증서와 키는 Git에 올리지 않습니다. 비밀번호나 토큰도 스크립트와 README에 기록하지 않습니다.
|