
서버리스, 피어투피어, 소리를 통한 로컬 파일 공유
WebRTC 시그널링을 사운드로 구현하는 개념 증명(PoC)입니다. 마이크와 스피커가 있는 모든 기기에서 작동하며 브라우저에서 실행됩니다.
주변 기기들은 오디오 톤 시퀀스를 통해 필요한 SDP(Session Description Protocol) 데이터를 교환하여 WebRTC 연결을 협상합니다. 협상이 성공하면 브라우저 간에 로컬 WebRTC 연결이 설정되어 LAN을 통해 데이터를 교환할 수 있습니다.
작동 영상 (2분):
직접 사용해보세요: ggerganov.github.io/wave-share
최신 소식:
사운드를 통한 데이터 전송 알고리즘을 ggwave라는 독립형 라이브러리로 추출했습니다.
다른 프로젝트에 쉽게 포함시킬 수 있습니다.
WebRTC 기술을 사용하면 서로 다른 기기에서 실행되는 두 브라우저가 연결되어 데이터를 교환할 수 있습니다. 플러그인을 설치하거나 애플리케이션을 다운로드할 필요가 없습니다. 연결을 시작하려면 피어들이 연락처 정보(IP 주소, 네트워크 포트, 세션 ID 등)를 교환합니다. 이 과정을 "시그널링"이라고 합니다. WebRTC 사양은 시그널링에 대한 표준을 정의하지 않습니다. 연락처 교환은 모든 프로토콜이나 기술로 수행할 수 있습니다.
이 프로젝트에서는 사운드를 통해 시그널링을 수행합니다. 시그널링 순서는 다음과 같습니다:

위에서 설명한 시그널링 순서는 시그널링 서버를 포함하지 않습니다. 따라서 사운드를 통한 시그널링을 사용하는 애플리케이션은 예를 들어 정적 웹 페이지에서 제공될 수 있습니다. 유일한 요구 사항은 오디오 출력/캡처 장치를 제어할 수 있어야 한다는 것입니다.
현재 접근 방식의 명백한 한계(기능)는 근처 기기(예: 같은 방 안)만 서로 연결할 수 있다는 점입니다. 또한 NAT를 사용할 수 없기 때문에 기기들은 동일한 로컬 네트워크에 연결되어 있어야 합니다.
사운드를 통해 전송되는 데이터에는 WebRTC 연결을 초기화하는 데 필요한 연락처 정보가 포함됩니다. 이 데이터는 SDP(Session Description Protocol) 형식으로 저장됩니다. 사운드를 통한 데이터 전송은 대역폭과 안정성 측면에서 상당한 제한이 있으므로 가능한 한 적은 데이터를 전송하는 것이 바람직합니다. 따라서 SDP에서 관련 없는 정보는 모두 제거하고 연결 설정에 필요한 필수 데이터만 전송합니다. 현재 최소 필수 SDP 데이터가 포함된 사운드 패킷의 형식은 다음과 같습니다:
오디오 패킷의 총 크기는 112바이트입니다. 현재 오디오 인코딩 알고리즘을 사용하면 SDP 패킷을 5~10초 내에 전송할 수 있습니다(사용된 Tx 프로토콜에 따라 다름). 더 느린 프로토콜을 사용하면 시끄러운 환경이나 통신 기기 간 거리가 먼 경우 더 안정적인 전송이 가능합니다.
현재 접근 방식은 다중 주파수 FSK(Frequency-Shift Keying) 변조 방식을 사용합니다. 전송할 데이터는 먼저 4비트 청크로 분할됩니다. 각 시점마다 6개의 톤을 사용하여 3바이트가 전송됩니다. 각 톤은 하나의 4비트 청크에 해당합니다. 6개의 톤은 4.5kHz 범위에서 96개의 동일 간격 주파수로 나누어 방출됩니다:
모든 프로토콜에 대해: dF = 46.875 Hz. 비초음파 프로토콜의 경우: F0 = 1875.000 Hz. 초음파 프로토콜의 경우: F0 = 15000.000 Hz.
편의를 위해 간단한 WebRTC 핵을 사용하여 사용자 컴퓨터의 로컬 IP 주소를 자동으로 감지하므로 수동으로 제공할 필요가 없습니다. 그러나 최신 WebRTC 사양에서는 보안상의 이유로 이를 불가능하게 하므로 언젠가는 이 "기능"이 모든 브라우저에서 작동하지 않게 될 것입니다. 예를 들어 Safari에서는 더 이상 작동하지 않습니다.
wave.wasmEmscripten 컴파일러가 필요합니다. compile.sh 스크립트를 실행하세요.
wave-share중요: 이 CLI 도구는 현재 독립형 라이브러리인 ggwave의 프로토타입이었습니다. 이 사운드 기반 데이터 통신 유형의 적용에 대한 더 최신 예제가 있으므로 꼭 확인해 보세요.
표준 입력에 텍스트를 입력하고 Enter를 누르면 전송되는 간단한 도구입니다.
# 빌드
git clone https://github.com/ggerganov/wave-share
cd wave-share && mkdir build && cd build
cmake ..
make
# 실행
./wave-share
다음은 CLI 도구 사용 방법을 보여주는 짧은 비디오입니다:
| 크기, [B] | 설명 |
|---|
| 1 | SDP 유형 - 오퍼 또는 응답 |
| 1 | 패킷 크기(바이트, ECC 바이트 제외) |
| 4 | 전송 피어의 IP 주소 |
| 2 | 통신에 사용될 네트워크 포트 |
| 32 | 세션 데이터의 SHA-256 지문 |
| 40 | ICE 자격 증명 - 16바이트 사용자 이름 + 24바이트 비밀번호 |
| 32 | 전송 중 오류 수정에 사용되는 ECC 수정 바이트 |
| 주파수, [Hz] | 값, [bits] | 주파수, [Hz] | 값, [bits] | ... | 주파수, [Hz] | 값, [bits] |
|---|
F0 + 00*dF | 청크 0: 0000 | F0 + 16*dF | 청크 1: 0000 | ... | F0 + 80*dF | 청크 5: 0000 |
F0 + 01*dF | 청크 0: 0001 | F0 + 17*dF | 청크 1: 0001 | ... | F0 + 81*dF | 청크 5: 0001 |
F0 + 02*dF | 청크 0: 0010 | F0 + 18*dF | 청크 1: 0010 | ... | F0 + 82*dF | 청크 5: 0010 |
| ... | ... | ... | ... | ... | ... | ... |
F0 + 14*dF | 청크 0: 1110 | F0 + 30*dF | 청크 1: 1110 | ... | F0 + 94*dF | 청크 5: 1110 |
F0 + 15*dF | 청크 0: 1111 | F0 + 31*dF | 청크 1: 1111 | ... | F0 + 95*dF | 청크 5: 1111 |