Skip to content

Commit 28a8fa0

Browse files
committed
feat: use native jetkvm-audio
1 parent c529c90 commit 28a8fa0

File tree

4 files changed

+17
-93
lines changed

4 files changed

+17
-93
lines changed

audio.go

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,14 @@
11
package kvm
22

33
import (
4-
"fmt"
5-
"net"
64
"os/exec"
7-
"sync"
8-
"syscall"
9-
"time"
105
)
116

12-
func startFFmpeg() (cmd *exec.Cmd, err error) {
13-
binaryPath := "/userdata/jetkvm/bin/ffmpeg"
14-
// Run the binary in the background
15-
cmd = exec.Command(binaryPath,
16-
"-f", "alsa",
17-
"-channels", "2",
18-
"-sample_rate", "48000",
19-
"-i", "hw:1,0",
20-
"-c:a", "libopus",
21-
"-b:a", "64k", // ought to be enough for anybody
22-
"-vbr", "off",
23-
"-frame_duration", "20",
24-
"-compression_level", "2",
25-
"-f", "rtp",
26-
"rtp://127.0.0.1:3333")
27-
28-
nativeOutputLock := sync.Mutex{}
29-
nativeStdout := &nativeOutput{
30-
mu: &nativeOutputLock,
31-
logger: nativeLogger.Info().Str("pipe", "stdout"),
32-
}
33-
nativeStderr := &nativeOutput{
34-
mu: &nativeOutputLock,
35-
logger: nativeLogger.Info().Str("pipe", "stderr"),
36-
}
37-
38-
// Redirect stdout and stderr to the current process
39-
cmd.Stdout = nativeStdout
40-
cmd.Stderr = nativeStderr
41-
42-
// Set the process group ID so we can kill the process and its children when this process exits
43-
cmd.SysProcAttr = &syscall.SysProcAttr{
44-
Setpgid: true,
45-
Pdeathsig: syscall.SIGKILL,
46-
}
47-
48-
// Start the command
49-
if err := cmd.Start(); err != nil {
50-
return nil, fmt.Errorf("failed to start binary: %w", err)
51-
}
52-
53-
return
7+
func runAudioClient() (cmd *exec.Cmd, err error) {
8+
return startNativeBinary("/userdata/jetkvm/bin/jetkvm_audio")
549
}
5510

56-
func StartRtpAudioServer(handleClient func(net.Conn)) {
57-
scopedLogger := nativeLogger.With().
58-
Logger()
59-
60-
listener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 3333})
61-
if err != nil {
62-
scopedLogger.Warn().Err(err).Msg("failed to start server")
63-
return
64-
}
65-
66-
scopedLogger.Info().Msg("server listening")
67-
68-
go func() {
69-
for {
70-
cmd, err := startFFmpeg()
71-
if err != nil {
72-
scopedLogger.Error().Err(err).Msg("failed to start ffmpeg")
73-
}
74-
err = cmd.Wait()
75-
scopedLogger.Error().Err(err).Msg("ffmpeg exited, restarting")
76-
time.Sleep(2 * time.Second)
77-
}
78-
}()
79-
80-
go handleClient(listener)
11+
func StartAudioServer() {
12+
nativeAudioSocketListener = StartNativeSocketServer("/var/run/jetkvm_audio.sock", handleAudioClient, false)
13+
nativeLogger.Debug().Msg("native app audio sock started")
8114
}

main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ func Main() {
7777

7878
// initialize usb gadget
7979
initUsbGadget()
80-
StartRtpAudioServer(handleAudioClient)
80+
81+
StartAudioServer()
82+
if _, err := runAudioClient(); err != nil {
83+
logger.Warn().Err(err).Msg("failed to run audio client")
84+
}
8185

8286
if err := setInitialVirtualMediaState(); err != nil {
8387
logger.Warn().Err(err).Msg("failed to set initial virtual media state")

native.go

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
"time"
1414

1515
"github.com/jetkvm/kvm/resource"
16-
"github.com/pion/rtp"
17-
1816
"github.com/pion/webrtc/v4/pkg/media"
1917
)
2018

@@ -107,6 +105,7 @@ func WriteCtrlMessage(message []byte) error {
107105

108106
var nativeCtrlSocketListener net.Listener //nolint:unused
109107
var nativeVideoSocketListener net.Listener //nolint:unused
108+
var nativeAudioSocketListener net.Listener //nolint:unused
110109

111110
var ctrlClientConnected = make(chan struct{})
112111

@@ -260,8 +259,6 @@ func handleAudioClient(conn net.Conn) {
260259

261260
scopedLogger.Info().Msg("native audio socket client connected")
262261
inboundPacket := make([]byte, maxAudioFrameSize)
263-
var timestamp uint32
264-
var packet rtp.Packet
265262
for {
266263
n, err := conn.Read(inboundPacket)
267264
if err != nil {
@@ -270,20 +267,10 @@ func handleAudioClient(conn net.Conn) {
270267
}
271268

272269
if currentSession != nil {
273-
if err := packet.Unmarshal(inboundPacket[:n]); err != nil {
274-
scopedLogger.Warn().Err(err).Msg("error unmarshalling audio socket packet")
275-
continue
276-
}
277-
278-
timestamp += 960
279-
packet.Header.Timestamp = timestamp
280-
buf, err := packet.Marshal()
281-
if err != nil {
282-
scopedLogger.Warn().Err(err).Msg("error marshalling packet")
283-
continue
284-
}
285-
286-
if _, err := currentSession.AudioTrack.Write(buf); err != nil {
270+
if err := currentSession.AudioTrack.WriteSample(media.Sample{
271+
Data: inboundPacket[:n],
272+
Duration: 20 * time.Millisecond,
273+
}); err != nil {
287274
scopedLogger.Warn().Err(err).Msg("error writing sample")
288275
}
289276
}

webrtc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
type Session struct {
1919
peerConnection *webrtc.PeerConnection
2020
VideoTrack *webrtc.TrackLocalStaticSample
21-
AudioTrack *webrtc.TrackLocalStaticRTP
21+
AudioTrack *webrtc.TrackLocalStaticSample
2222
ControlChannel *webrtc.DataChannel
2323
RPCChannel *webrtc.DataChannel
2424
HidChannel *webrtc.DataChannel
@@ -137,7 +137,7 @@ func newSession(config SessionConfig) (*Session, error) {
137137
return nil, err
138138
}
139139

140-
session.AudioTrack, err = webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus}, "audio", "kvm")
140+
session.AudioTrack, err = webrtc.NewTrackLocalStaticSample(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus}, "audio", "kvm")
141141
if err != nil {
142142
return nil, err
143143
}

0 commit comments

Comments
 (0)