Skip to content

Commit cd5d7e2

Browse files
committed
add lk console command with PortAudio + WebRTC AEC
1 parent 43c8e51 commit cd5d7e2

1,481 files changed

Lines changed: 266524 additions & 35 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
pkg/provider/resources/*.h264 filter=lfs diff=lfs merge=lfs -text
22
pkg/provider/resources/*.ivf filter=lfs diff=lfs merge=lfs -text
33
pkg/provider/resources/*.ogg filter=lfs diff=lfs merge=lfs -text
4+
5+
# Vendored C/C++ source (WebRTC APM, PortAudio, abseil, pffft, rnnoise)
6+
pkg/apm/webrtc/**/*.cc linguist-vendored
7+
pkg/apm/webrtc/**/*.c linguist-vendored
8+
pkg/apm/webrtc/**/*.h linguist-vendored
9+
pkg/apm/webrtc/**/*.m linguist-vendored
10+
pkg/apm/webrtc/**/*.inc linguist-vendored
11+
pkg/portaudio/pa_src/** linguist-vendored

.github/workflows/build.yaml

Lines changed: 128 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,149 @@ on:
2020
pull_request:
2121
branches: [ main ]
2222

23+
permissions:
24+
contents: read
25+
2326
jobs:
24-
build:
27+
lint-and-test:
2528
runs-on: ubuntu-latest
2629
steps:
2730
- uses: actions/checkout@v6
28-
- uses: actions/cache@v5
2931
with:
30-
path: |
31-
~/go/pkg/mod
32-
~/go/bin
33-
~/.cache
34-
key: livekit-cli
32+
submodules: true
3533

3634
- name: Set up Go
3735
uses: actions/setup-go@v6
3836
with:
3937
go-version: "1.25"
4038

41-
- name: Download Go modules
42-
run: go mod download
43-
4439
- name: Static Check
4540
uses: dominikh/staticcheck-action@v1.4.0
4641
with:
4742
version: "latest"
4843
install-go: false
4944

50-
- name: Run Go tests
45+
- name: Test
5146
run: go test -v ./...
47+
48+
build:
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
include:
53+
- os: macos-latest
54+
suffix: darwin_arm64
55+
- os: ubuntu-latest
56+
suffix: linux_amd64
57+
zig_target: x86_64-linux-gnu.2.28
58+
alsa_arch: amd64
59+
alsa_triple: x86_64-linux-gnu
60+
- os: ubuntu-latest
61+
suffix: linux_arm64
62+
zig_target: aarch64-linux-gnu.2.28
63+
alsa_arch: arm64
64+
alsa_triple: aarch64-linux-gnu
65+
goarch: arm64
66+
- os: ubuntu-latest
67+
suffix: linux_arm
68+
zig_target: arm-linux-gnueabihf.2.28
69+
alsa_arch: armhf
70+
alsa_triple: arm-linux-gnueabihf
71+
goarch: arm
72+
goarm: "7"
73+
- os: ubuntu-latest
74+
suffix: windows_amd64
75+
zig_target: x86_64-windows-gnu
76+
goos: windows
77+
goarch: amd64
78+
- os: ubuntu-latest
79+
suffix: windows_arm64
80+
zig_target: aarch64-windows-gnu
81+
goos: windows
82+
goarch: arm64
83+
- os: ubuntu-latest
84+
suffix: windows_arm
85+
goos: windows
86+
goarch: arm
87+
goarm: "7"
88+
runs-on: ${{ matrix.os }}
89+
steps:
90+
- uses: actions/checkout@v6
91+
with:
92+
submodules: true
93+
94+
- name: Set up Go
95+
uses: actions/setup-go@v6
96+
with:
97+
go-version: "1.25"
98+
99+
- name: Install Zig
100+
if: matrix.zig_target
101+
uses: mlugg/setup-zig@v2
102+
with:
103+
version: 0.14.1
104+
105+
- name: Install ALSA headers
106+
if: matrix.alsa_arch
107+
run: |
108+
sudo dpkg --add-architecture ${{ matrix.alsa_arch }}
109+
if [ "${{ matrix.alsa_arch }}" != "amd64" ]; then
110+
CODENAME=$(lsb_release -cs)
111+
# Restrict existing sources to amd64 to avoid 404s for foreign arch
112+
for f in /etc/apt/sources.list.d/*.sources; do
113+
grep -q '^Architectures:' "$f" || sudo sed -i '/^Types:/a Architectures: amd64 i386' "$f"
114+
done
115+
# Add ports.ubuntu.com for the foreign architecture
116+
printf 'Types: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: %s %s-updates\nComponents: main universe\nArchitectures: %s\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \
117+
"$CODENAME" "$CODENAME" "${{ matrix.alsa_arch }}" | sudo tee /etc/apt/sources.list.d/ports.sources
118+
fi
119+
sudo apt-get update
120+
sudo apt-get install -y libasound2-dev:${{ matrix.alsa_arch }}
121+
122+
- name: Generate Windows import libraries
123+
if: matrix.goos == 'windows' && matrix.zig_target
124+
run: |
125+
ZIG_LIB=$(zig env | jq -r '.lib_dir')
126+
echo "ZIG_LIB=${ZIG_LIB}" >> "$GITHUB_ENV"
127+
LIB_DIR="${ZIG_LIB}/libc/mingw/lib-common"
128+
# Zig bundles MinGW .def files but lld needs .a import libraries.
129+
# Go's compiled objects embed COFF /DEFAULTLIB directives (e.g. dbghelp,
130+
# bcrypt) that lld resolves directly, bypassing Zig's lazy .def→.a
131+
# generation. Pre-generate all import libraries so lld can find them.
132+
MACHINE=${{ matrix.goarch == 'amd64' && 'i386:x86-64' || 'arm64' }}
133+
for def in "${LIB_DIR}"/*.def; do
134+
lib=$(basename "$def" .def)
135+
[ -f "${LIB_DIR}/lib${lib}.a" ] && continue
136+
zig dlltool -d "$def" -l "${LIB_DIR}/lib${lib}.a" -m "$MACHINE" 2>/dev/null || true
137+
done
138+
139+
- name: Build
140+
env:
141+
CGO_ENABLED: ${{ (matrix.goos && !matrix.zig_target) && '0' || '1' }}
142+
CC: ${{ matrix.zig_target && format('zig cc -target {0}', matrix.zig_target) || '' }}
143+
CXX: ${{ matrix.zig_target && format('zig c++ -target {0}', matrix.zig_target) || '' }}
144+
# Zig uses its own sysroot; point it at the system ALSA headers and libraries
145+
CGO_CFLAGS: ${{ matrix.alsa_triple && format('-isystem /usr/include -isystem /usr/include/{0}', matrix.alsa_triple) || '' }}
146+
CGO_LDFLAGS: ${{ matrix.alsa_triple && format('-L/usr/lib/{0}', matrix.alsa_triple) || '' }}
147+
# -fms-extensions: enable __try/__except (SEH) used by WebRTC
148+
# -DNTDDI_VERSION: target Windows 10 base to skip WinRT includes absent from MinGW
149+
CGO_CXXFLAGS: ${{ matrix.goos == 'windows' && '-fms-extensions -DNTDDI_VERSION=0x0A000000' || '' }}
150+
GOOS: ${{ matrix.goos || '' }}
151+
GOARCH: ${{ matrix.goarch || '' }}
152+
GOARM: ${{ matrix.goarm || '' }}
153+
shell: bash
154+
run: |
155+
EXT=""; if [ "${GOOS:-}" = "windows" ]; then EXT=".exe"; fi
156+
TAGS=""
157+
if [ "$CGO_ENABLED" = "1" ]; then TAGS="-tags console"; fi
158+
# Force external linking for Windows so Go uses zig cc (CC) as the linker,
159+
# and add Zig's MinGW lib path so lld can find the generated import libraries.
160+
EXTLD=""
161+
if [ "${GOOS:-}" = "windows" ] && [ "$CGO_ENABLED" = "1" ]; then
162+
EXTLD="-linkmode=external -extldflags '-L${ZIG_LIB}/libc/mingw/lib-common'"
163+
fi
164+
go build $TAGS -ldflags "-w -s $EXTLD" -o "bin/lk${EXT}" ./cmd/lk
165+
166+
- name: Verify binary
167+
if: "!matrix.goos && !matrix.goarch"
168+
run: bin/lk --help > /dev/null

.github/workflows/release.yaml

Lines changed: 138 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
name: Release
1616

17-
# on events
1817
on:
1918
push:
2019
tags:
@@ -23,17 +22,14 @@ on:
2322
permissions:
2423
contents: write
2524

26-
# workflow tasks
2725
jobs:
28-
release:
29-
name: Release
26+
create-release:
3027
runs-on: ubuntu-latest
3128
steps:
32-
- name: Checkout Git LFS
33-
uses: actions/checkout@v6
29+
- uses: actions/checkout@v6
3430
with:
3531
lfs: 'true'
36-
32+
3733
- name: Verify version.go matches tag
3834
run: |
3935
TAG_VERSION=${GITHUB_REF#refs/tags/v}
@@ -47,7 +43,7 @@ jobs:
4743
exit 1
4844
fi
4945
echo "✓ Versions match: $CODE_VERSION"
50-
46+
5147
- name: Verify server-sdk-go version
5248
run: |
5349
livekit_cli_ver=${GITHUB_REF#refs/tags/}
@@ -65,29 +61,147 @@ jobs:
6561
fi
6662
echo "versions match ($livekit_cli_major_minor)"
6763
68-
- run: git lfs pull
69-
70-
- name: Fetch all tags
71-
run: git fetch --force --tags
64+
- name: Create release
65+
env:
66+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
run: |
68+
TAG="${GITHUB_REF#refs/tags/}"
69+
gh release create "$TAG" --draft --generate-notes --title "$TAG"
7270
73-
- uses: actions/cache@v5
71+
build:
72+
needs: create-release
73+
strategy:
74+
fail-fast: false
75+
matrix:
76+
include:
77+
- os: macos-latest
78+
suffix: darwin_arm64
79+
- os: ubuntu-latest
80+
suffix: linux_amd64
81+
zig_target: x86_64-linux-gnu.2.28
82+
alsa_arch: amd64
83+
alsa_triple: x86_64-linux-gnu
84+
- os: ubuntu-latest
85+
suffix: linux_arm64
86+
zig_target: aarch64-linux-gnu.2.28
87+
alsa_arch: arm64
88+
alsa_triple: aarch64-linux-gnu
89+
goarch: arm64
90+
- os: ubuntu-latest
91+
suffix: linux_arm
92+
zig_target: arm-linux-gnueabihf.2.28
93+
alsa_arch: armhf
94+
alsa_triple: arm-linux-gnueabihf
95+
goarch: arm
96+
goarm: "7"
97+
- os: ubuntu-latest
98+
suffix: windows_amd64
99+
zig_target: x86_64-windows-gnu
100+
goos: windows
101+
goarch: amd64
102+
- os: ubuntu-latest
103+
suffix: windows_arm64
104+
zig_target: aarch64-windows-gnu
105+
goos: windows
106+
goarch: arm64
107+
- os: ubuntu-latest
108+
suffix: windows_arm
109+
goos: windows
110+
goarch: arm
111+
goarm: "7"
112+
runs-on: ${{ matrix.os }}
113+
steps:
114+
- uses: actions/checkout@v6
74115
with:
75-
path: |
76-
~/go/pkg/mod
77-
~/go/bin
78-
~/.cache
79-
key: livekit-cli
116+
lfs: 'true'
117+
submodules: true
118+
119+
- run: git lfs pull
80120

81121
- name: Set up Go
82122
uses: actions/setup-go@v6
83123
with:
84124
go-version: "1.25"
85125

86-
- name: Run GoReleaser
87-
uses: goreleaser/goreleaser-action@v6
126+
- name: Install Zig
127+
if: matrix.zig_target
128+
uses: mlugg/setup-zig@v2
88129
with:
89-
distribution: goreleaser
90-
version: latest
91-
args: release --clean
130+
version: 0.14.1
131+
132+
- name: Install ALSA headers
133+
if: matrix.alsa_arch
134+
run: |
135+
sudo dpkg --add-architecture ${{ matrix.alsa_arch }}
136+
if [ "${{ matrix.alsa_arch }}" != "amd64" ]; then
137+
CODENAME=$(lsb_release -cs)
138+
# Restrict existing sources to amd64 to avoid 404s for foreign arch
139+
for f in /etc/apt/sources.list.d/*.sources; do
140+
grep -q '^Architectures:' "$f" || sudo sed -i '/^Types:/a Architectures: amd64 i386' "$f"
141+
done
142+
# Add ports.ubuntu.com for the foreign architecture
143+
printf 'Types: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: %s %s-updates\nComponents: main universe\nArchitectures: %s\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \
144+
"$CODENAME" "$CODENAME" "${{ matrix.alsa_arch }}" | sudo tee /etc/apt/sources.list.d/ports.sources
145+
fi
146+
sudo apt-get update
147+
sudo apt-get install -y libasound2-dev:${{ matrix.alsa_arch }}
148+
149+
- name: Generate Windows import libraries
150+
if: matrix.goos == 'windows' && matrix.zig_target
151+
run: |
152+
ZIG_LIB=$(zig env | jq -r '.lib_dir')
153+
echo "ZIG_LIB=${ZIG_LIB}" >> "$GITHUB_ENV"
154+
LIB_DIR="${ZIG_LIB}/libc/mingw/lib-common"
155+
# Zig bundles MinGW .def files but lld needs .a import libraries.
156+
# Go's compiled objects embed COFF /DEFAULTLIB directives (e.g. dbghelp,
157+
# bcrypt) that lld resolves directly, bypassing Zig's lazy .def→.a
158+
# generation. Pre-generate all import libraries so lld can find them.
159+
MACHINE=${{ matrix.goarch == 'amd64' && 'i386:x86-64' || 'arm64' }}
160+
for def in "${LIB_DIR}"/*.def; do
161+
lib=$(basename "$def" .def)
162+
[ -f "${LIB_DIR}/lib${lib}.a" ] && continue
163+
zig dlltool -d "$def" -l "${LIB_DIR}/lib${lib}.a" -m "$MACHINE" 2>/dev/null || true
164+
done
165+
166+
- name: Build
92167
env:
93-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168+
CGO_ENABLED: ${{ (matrix.goos && !matrix.zig_target) && '0' || '1' }}
169+
CC: ${{ matrix.zig_target && format('zig cc -target {0}', matrix.zig_target) || '' }}
170+
CXX: ${{ matrix.zig_target && format('zig c++ -target {0}', matrix.zig_target) || '' }}
171+
# Zig uses its own sysroot; point it at the system ALSA headers and libraries
172+
CGO_CFLAGS: ${{ matrix.alsa_triple && format('-isystem /usr/include -isystem /usr/include/{0}', matrix.alsa_triple) || '' }}
173+
CGO_LDFLAGS: ${{ matrix.alsa_triple && format('-L/usr/lib/{0}', matrix.alsa_triple) || '' }}
174+
# -fms-extensions: enable __try/__except (SEH) used by WebRTC
175+
# -DNTDDI_VERSION: target Windows 10 base to skip WinRT includes absent from MinGW
176+
CGO_CXXFLAGS: ${{ matrix.goos == 'windows' && '-fms-extensions -DNTDDI_VERSION=0x0A000000' || '' }}
177+
GOOS: ${{ matrix.goos || '' }}
178+
GOARCH: ${{ matrix.goarch || '' }}
179+
GOARM: ${{ matrix.goarm || '' }}
180+
shell: bash
181+
run: |
182+
EXT=""; if [ "${GOOS:-}" = "windows" ]; then EXT=".exe"; fi
183+
TAGS=""
184+
if [ "$CGO_ENABLED" = "1" ]; then TAGS="-tags console"; fi
185+
# Force external linking for Windows so Go uses zig cc (CC) as the linker,
186+
# and add Zig's MinGW lib path so lld can find the generated import libraries.
187+
EXTLD=""
188+
if [ "${GOOS:-}" = "windows" ] && [ "$CGO_ENABLED" = "1" ]; then
189+
EXTLD="-linkmode=external -extldflags '-L${ZIG_LIB}/libc/mingw/lib-common'"
190+
fi
191+
go build $TAGS -ldflags "-w -s $EXTLD" -o "dist/lk${EXT}" ./cmd/lk
192+
193+
- name: Package and upload
194+
env:
195+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
196+
shell: bash
197+
run: |
198+
TAG="${GITHUB_REF#refs/tags/}"
199+
NAME="lk_${TAG}_${{ matrix.suffix }}"
200+
cp LICENSE dist/
201+
if [[ "${{ matrix.suffix }}" == windows_* ]]; then
202+
cd dist && zip "../${NAME}.zip" lk.exe LICENSE && cd ..
203+
gh release upload "$TAG" "${NAME}.zip" --clobber
204+
else
205+
tar -czf "${NAME}.tar.gz" -C dist lk LICENSE
206+
gh release upload "$TAG" "${NAME}.tar.gz" --clobber
207+
fi

.github/workflows/test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020

2121
steps:
2222
- uses: actions/checkout@v6
23+
with:
24+
submodules: true
2325

2426
- name: Set up Go
2527
uses: actions/setup-go@v6

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "pkg/portaudio/pa_src"]
2+
path = pkg/portaudio/pa_src
3+
url = https://github.com/PortAudio/portaudio.git

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ cli: check_lfs
1616
GOOS=windows GOARCH=amd64 go build -ldflags "-w -s" -o bin/lk.exe ./cmd/lk
1717

1818

19+
console:
20+
CGO_ENABLED=1 go build -tags console -ldflags "-w -s" -o bin/lk ./cmd/lk
21+
1922
install: cli
2023
ifeq ($(DETECTED_OS),Windows)
2124
cp bin/lk.exe $(GOBIN)/lk.exe

0 commit comments

Comments
 (0)