Add automatic microphone mixing and single FFmpeg pipeline
This commit is contained in:
1 parent
2819d31490
commit
f11e636826
3 files changed
+436
-138
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# RTSP
|
||||
|
||||
Windows의 활성 모니터를 독립 RTSP 채널로 송출하고, 실제 재생 신호가 있는 오디오 출력 장치를 자동 선택해 시스템 소리를 함께 전송하는 PowerShell 기반 watchdog입니다.
|
||||
Windows의 활성 모니터를 독립 RTSP 채널로 송출하고, 실제 신호가 있는 시스템 재생 장치와 마이크를 자동 선택해 혼합 오디오를 함께 전송하는 PowerShell 기반 watchdog입니다.
|
||||
|
||||
## 프로젝트 성격
|
||||
|
||||
@@ -20,13 +20,16 @@ RTSP는 `ddagrab` 기반 Desktop Duplication API로 화면과 마우스 커서
|
||||
- 기본 우선순위 `NVIDIA > AMD > Intel`, 실행 인자로 변경 가능
|
||||
- Windows Core Audio WASAPI loopback 기반 시스템 재생음 캡처
|
||||
- 실제 오디오 peak가 있는 출력 장치 우선 선택
|
||||
- 무음 상태에서는 기본 출력 장치를 유지해 송출이 불필요하게 끊기지 않음
|
||||
- 기본 출력 장치, 재생 장치, 오디오 포맷 변경 시 전체 채널 재시작
|
||||
- 활성 마이크 입력 endpoint 자동 검색 및 실제 입력 peak 기반 선택
|
||||
- 무음 상태에서는 Windows 기본 출력·입력 장치를 선택해 송출이 불필요하게 끊기지 않음
|
||||
- DirectShow 마이크와 시스템 재생음을 `amix`로 혼합하고 `asplit`으로 모든 채널에 분배
|
||||
- 하나의 FFmpeg가 모든 DDA 입력과 RTSP 출력을 함께 처리
|
||||
- 기본 출력·입력 장치, 선택 장치, 오디오 포맷 변경 시 전체 채널 재시작
|
||||
- 기본 30fps, 영상 8Mbps, AAC 오디오 192kbps
|
||||
- NIC Link, IPv4, `ifIndex`, IP 변경 감지
|
||||
- 선택적 Source IP 고정 ping 상태 검사
|
||||
- 3초간 정상 상태가 유지된 뒤 전체 채널 시작
|
||||
- FFmpeg 또는 오디오 worker 하나가 종료되면 전체 채널 재시작
|
||||
- 단일 FFmpeg 또는 WASAPI loopback worker가 종료되면 전체 채널 재시작
|
||||
- MediaMTX 종료 시 자동 재시작
|
||||
- 기존 MediaMTX가 RTSP 포트를 사용 중이면 해당 프로세스 재사용
|
||||
- 자동 생성 MediaMTX 설정은 RTSP over TCP만 사용해 UDP RTP 포트 충돌 방지
|
||||
@@ -35,9 +38,9 @@ RTSP는 `ddagrab` 기반 Desktop Duplication API로 화면과 마우스 커서
|
||||
- 절전 해제나 장시간 polling 중단 감지 시 전체 채널 강제 재구성
|
||||
- 로그인 트리거와 1분 간격 무기한 복구 트리거를 이용한 Watchdog 지속 복구
|
||||
- `config.ini` 기반 기능별 설정과 명령줄 override
|
||||
- 오디오 캡처/AAC 트랙을 `1` 또는 `0`으로 활성화·비활성화
|
||||
- 전체 오디오와 마이크 혼합을 각각 `1` 또는 `0`으로 활성화·비활성화
|
||||
- FFmpeg와 MediaMTX 부재 시 HTTPS 다운로드, SHA-256 검증, 자동 설치
|
||||
- 모니터·오디오·NIC·프로세스·절전 복구·설정·안전장치용 내장 시뮬레이션 35건
|
||||
- 모니터·오디오·NIC·프로세스·절전 복구·설정·안전장치용 내장 시뮬레이션 42건
|
||||
|
||||
## RTSP URL
|
||||
|
||||
@@ -48,17 +51,33 @@ rtsp://<현재_NIC_IP>:8554/monitor1
|
||||
rtsp://<현재_NIC_IP>:8554/monitor2
|
||||
```
|
||||
|
||||
## 프로세스 구조
|
||||
|
||||
기본 2채널에서는 화면·오디오 입력을 하나의 FFmpeg가 열고 두 RTSP 출력을 동시에 publish합니다.
|
||||
|
||||
```text
|
||||
ddagrab monitor 1 ───────────────────────────────┐
|
||||
ddagrab monitor 2 ───────────────────────────────┤
|
||||
│
|
||||
WASAPI 출력 loopback worker → named pipe ─┐ ├─ FFmpeg 1개
|
||||
├─amix│ ├─ /monitor1
|
||||
자동 선택 마이크 → DirectShow ────────────┘ │ └─ /monitor2
|
||||
│
|
||||
amix → asplit
|
||||
```
|
||||
|
||||
`ChannelCount`를 늘리면 동일한 단일 FFmpeg 안에서 선택된 화면 수만큼 DDA 입력과 RTSP 출력을 만들고, 혼합 오디오도 같은 수만큼 분배합니다.
|
||||
|
||||
## 구성
|
||||
|
||||
- `screen-rtsp.ps1`: 캡처, 오디오 loopback, GPU 선택, MediaMTX/FFmpeg watchdog
|
||||
- `config.ini`: 영상, 오디오, 네트워크, RTSP 설정과 진단 명령 예시
|
||||
- `ffmpeg.exe`: `ddagrab`, `h264_nvenc`, `h264_amf`, `h264_qsv`, `aac` 지원 FFmpeg
|
||||
- `ffmpeg.exe`: `ddagrab`, `dshow`, `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 오류 로그
|
||||
- `logs/ffmpeg.log`: 모든 monitor 출력을 담당하는 단일 FFmpeg 로그
|
||||
- `logs/audio-loopback.log`: 단일 WASAPI loopback worker 오류 로그
|
||||
|
||||
실행 파일과 생성 파일은 저장소에 포함하지 않습니다. `Dependencies.AutoInstall=1`이면 실행할 때 없는 `ffmpeg.exe`와 `mediamtx.exe`를 스크립트 옆에 자동 설치합니다.
|
||||
|
||||
@@ -74,11 +93,12 @@ EncoderPriority=NVIDIA,AMD,Intel
|
||||
|
||||
[Audio]
|
||||
Enabled=1
|
||||
MicrophoneEnabled=1
|
||||
Bitrate=192k
|
||||
SignalThreshold=0.0005
|
||||
```
|
||||
|
||||
`Audio.Enabled=1`이면 현재 재생 장치의 시스템 소리를 WASAPI loopback으로 캡처해 AAC 트랙을 추가합니다. `0`이면 오디오 장치 감시, loopback worker, AAC 트랙을 모두 사용하지 않고 영상만 송출합니다.
|
||||
`Audio.Enabled=1`이면 선택한 출력 장치의 시스템 재생음을 WASAPI loopback으로 캡처합니다. `MicrophoneEnabled=1`이면 자동 선택한 마이크를 DirectShow로 열고 시스템 재생음과 혼합합니다. `Audio.Enabled=0`이면 마이크 설정과 관계없이 모든 오디오 감시와 AAC 트랙을 끄고 영상만 송출합니다.
|
||||
|
||||
줄 앞의 공백을 제외한 첫 문자가 `#`, `;`, `//`이면 설명이나 참고 명령으로 인식해 건너뜁니다. 값 오른쪽의 inline 주석은 지원하지 않으므로 설명은 별도 줄에 작성합니다. 명령줄에서 직접 지정한 값은 INI 값보다 우선합니다.
|
||||
|
||||
@@ -93,8 +113,9 @@ SignalThreshold=0.0005
|
||||
| `Video` | `Bitrate` | `8000k` | 채널별 영상 비트레이트 |
|
||||
| `Video` | `EncoderPriority` | `NVIDIA,AMD,Intel` | GPU 선택 순서 |
|
||||
| `Audio` | `Enabled` | `1` | 시스템 재생음과 AAC 트랙 사용 여부 |
|
||||
| `Audio` | `MicrophoneEnabled` | `1` | 마이크 자동 선택 및 시스템 재생음 혼합 여부 |
|
||||
| `Audio` | `Bitrate` | `192k` | AAC 비트레이트 |
|
||||
| `Audio` | `SignalThreshold` | `0.0005` | 실제 재생 장치 판별 peak 기준 |
|
||||
| `Audio` | `SignalThreshold` | `0.0005` | 실제 출력·입력 신호 장치 판별 peak 기준 |
|
||||
| `Network` | `NicDescription` | 빈 값 | 비우면 기본 경로 NIC 자동 선택 |
|
||||
| `Network` | `HealthTarget` | 빈 값 | Source IP ping 대상 |
|
||||
| `RTSP` | `Port` | `8554` | MediaMTX RTSP 포트 |
|
||||
@@ -135,7 +156,7 @@ INI를 해석한 최종 설정값만 확인하고 종료할 수도 있습니다.
|
||||
|
||||
## 내장 시뮬레이션
|
||||
|
||||
실제 송출 프로세스나 예약 작업을 만들지 않고 주요 판단 로직 35건을 검사합니다.
|
||||
실제 송출 프로세스나 예약 작업을 만들지 않고 주요 판단 로직 42건을 검사합니다.
|
||||
|
||||
```powershell
|
||||
.\screen-rtsp.ps1 -RunSimulationTests
|
||||
@@ -147,11 +168,11 @@ INI를 해석한 최종 설정값만 확인하고 종료할 수도 있습니다.
|
||||
|
||||
1. FFmpeg와 MediaMTX가 없으면 설정에 따라 다운로드·검증·설치한 뒤, FFmpeg의 `ddagrab`과 H.264 하드웨어 인코더 포함 여부를 확인합니다.
|
||||
2. 설치된 GPU를 `NVIDIA > AMD > Intel` 순서로 찾고 각 인코더를 실제 1프레임으로 초기화합니다.
|
||||
3. 활성 모니터, IPv4 기본 경로 NIC, 활성 오디오 출력 장치를 읽습니다.
|
||||
4. Core Audio peak가 감지된 출력 장치를 우선하고, 신호가 없으면 Windows 기본 출력 장치를 사용합니다.
|
||||
5. 모든 조건이 3초 동안 유지되면 채널마다 WASAPI loopback worker와 FFmpeg를 시작합니다.
|
||||
3. 활성 모니터, IPv4 기본 경로 NIC, 활성 오디오 출력·입력 endpoint를 읽습니다.
|
||||
4. Core Audio peak가 감지된 출력 장치와 마이크를 우선하고, 신호가 없으면 Windows 기본 Multimedia 장치를 사용합니다.
|
||||
5. 모든 조건이 3초 동안 유지되면 WASAPI loopback worker 하나와 FFmpeg 하나를 시작합니다.
|
||||
6. 화면은 `ddagrab -> hwdownload -> BGRA -> 회전 보정 -> NV12 -> 하드웨어 H.264` 순서로 처리합니다.
|
||||
7. 시스템 소리는 named pipe를 통해 FFmpeg로 전달하고 AAC로 인코딩합니다.
|
||||
7. 시스템 소리는 named pipe, 마이크는 DirectShow로 FFmpeg에 입력됩니다. 두 소리를 `amix`한 뒤 `asplit`으로 각 RTSP 출력에 넣고 AAC로 인코딩합니다.
|
||||
8. 모니터, NIC, GPU, 오디오 장치 또는 자식 프로세스 상태가 바뀌면 전체 채널을 종료한 뒤 새 구성을 읽어 재시작합니다.
|
||||
|
||||
## 설치 및 실행
|
||||
@@ -185,7 +206,7 @@ Start-ScheduledTask -TaskName "Screen RTSP Watchdog"
|
||||
- 절전 중 놓친 실행은 `StartWhenAvailable`로 절전 해제 후 시작
|
||||
- 배터리 전환 시에도 중지하지 않으며 실행 시간 제한 없음
|
||||
|
||||
Watchdog 내부에서는 Windows `PowerModeChanged/Resume` 이벤트를 감시하고, 이벤트 누락에 대비해 polling 시간 공백도 함께 확인합니다. 절전 해제가 감지되면 FFmpeg 2채널을 모두 종료하고 모니터·NIC·오디오·GPU 구성을 다시 읽은 뒤 안정화 시간 이후 재시작합니다. 모니터 분리 시에는 채널을 종료하고 계속 대기하며, 필요한 수만큼 다시 연결되면 동일하게 자동 복구합니다.
|
||||
Watchdog 내부에서는 Windows `PowerModeChanged/Resume` 이벤트를 감시하고, 이벤트 누락에 대비해 polling 시간 공백도 함께 확인합니다. 절전 해제가 감지되면 단일 FFmpeg AV 파이프라인을 종료하고 모니터·NIC·오디오·GPU 구성을 다시 읽은 뒤 안정화 시간 이후 재시작합니다. 모니터 분리 시에는 채널을 종료하고 계속 대기하며, 필요한 수만큼 다시 연결되면 동일하게 자동 복구합니다.
|
||||
|
||||
등록된 작업은 `config.ini` 경로만 전달하므로 설정 파일을 수정한 뒤 작업을 다시 시작하면 변경값이 적용됩니다. 기존 작업이 등록돼 있다면 업데이트된 복구 설정을 적용하기 위해 `-InstallStartup`을 다시 실행해야 합니다.
|
||||
|
||||
@@ -219,6 +240,12 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\screen-rtsp.ps1 -Unins
|
||||
.\screen-rtsp.ps1 -AudioEnabled 0
|
||||
```
|
||||
|
||||
시스템 재생음은 유지하고 마이크만 끄는 예시:
|
||||
|
||||
```powershell
|
||||
.\screen-rtsp.ps1 -MicrophoneEnabled 0
|
||||
```
|
||||
|
||||
GPU 우선순위를 바꾸는 예시:
|
||||
|
||||
```powershell
|
||||
@@ -243,14 +270,16 @@ GPU 우선순위를 바꾸는 예시:
|
||||
|
||||
## 오디오 장치 선택 정책
|
||||
|
||||
스크립트는 활성 상태의 Windows Render endpoint를 모두 읽고 각 장치의 peak를 확인합니다.
|
||||
스크립트는 활성 상태의 Windows Render와 Capture endpoint를 모두 읽고 각 장치의 peak를 확인합니다.
|
||||
|
||||
- 현재 선택 장치에 실제 신호가 계속 있으면 해당 장치를 유지합니다.
|
||||
- 다른 활성 장치에서만 신호가 감지되면 해당 장치로 전환합니다.
|
||||
- 모든 장치가 무음이면 Windows 기본 Multimedia 출력 장치를 선택합니다.
|
||||
- 선택 장치가 제거되거나 기본 장치와 mix format이 바뀌면 전체 RTSP 채널을 재시작합니다.
|
||||
- 현재 선택한 출력 또는 입력 장치에 실제 신호가 계속 있으면 해당 장치를 유지합니다.
|
||||
- 다른 활성 장치에서만 신호가 감지되면 해당 출력 장치 또는 마이크로 전환합니다.
|
||||
- 모든 장치가 무음이면 Windows 기본 Multimedia 출력·입력 장치를 선택합니다.
|
||||
- 선택 endpoint ID, 기본 장치 여부, sample rate, 채널 수 또는 sample format이 바뀌면 전체 RTSP 채널을 재시작합니다.
|
||||
- Core Audio와 DirectShow가 장치명 공백을 다르게 표시해도 정규화해 같은 마이크로 연결합니다.
|
||||
- 마이크가 활성화된 상태에서 입력 장치가 없으면 영상만 보내지 않고 정상 입력 장치가 생길 때까지 전체 파이프라인을 대기합니다.
|
||||
|
||||
이 정책은 음악이나 알림 사이의 무음 구간마다 송출이 중단되는 것을 막으면서, Bluetooth/HDMI/USB 오디오처럼 실제 재생 장치가 바뀌는 상황을 자동 반영합니다.
|
||||
이 정책은 음악이나 음성 사이의 무음 구간마다 송출이 중단되는 것을 막으면서 Bluetooth/HDMI/USB 출력과 USB/Bluetooth 마이크 변경을 자동 반영합니다.
|
||||
|
||||
## 운영 체크포인트
|
||||
|
||||
|
||||
Reference in new issue
Block a user