diff --git a/internal/core/webrtc_http_server.go b/internal/core/webrtc_http_server.go
index f7edd842..16e58a5a 100644
--- a/internal/core/webrtc_http_server.go
+++ b/internal/core/webrtc_http_server.go
@@ -305,6 +305,7 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
audioCodec: ctx.Query("audio_codec"),
videoBitrate: ctx.Query("video_bitrate"),
audioBitrate: ctx.Query("audio_bitrate"),
+ audioVoice: ctx.Query("audio_voice") == "true",
})
if res.err != nil {
if res.errStatusCode != 0 {
diff --git a/internal/core/webrtc_manager.go b/internal/core/webrtc_manager.go
index 23f85bad..95e982e4 100644
--- a/internal/core/webrtc_manager.go
+++ b/internal/core/webrtc_manager.go
@@ -138,6 +138,7 @@ type webRTCSessionNewReq struct {
audioCodec string
videoBitrate string
audioBitrate string
+ audioVoice bool
res chan webRTCSessionNewRes
}
diff --git a/internal/core/webrtc_publish_index.html b/internal/core/webrtc_publish_index.html
index 44adf3dc..dda86de4 100644
--- a/internal/core/webrtc_publish_index.html
+++ b/internal/core/webrtc_publish_index.html
@@ -75,6 +75,11 @@ select {
audio bitrate (kbps):
+
+
+
+
+
@@ -226,12 +231,14 @@ class Transmitter {
const audioCodec = document.getElementById('audio_codec').value;
const videoBitrate = document.getElementById('video_bitrate').value;
const audioBitrate = document.getElementById('audio_bitrate').value;
+ const audioVoice = document.getElementById('audio_voice').checked;
const p = new URLSearchParams(window.location.search);
p.set('video_codec', videoCodec);
p.set('audio_codec', audioCodec);
p.set('video_bitrate', videoBitrate);
p.set('audio_bitrate', audioBitrate);
+ p.set('audio_voice', audioVoice ? 'true' : 'false');
fetch(new URL('whip', window.location.href) + '?' + p.toString(), {
method: 'POST',
@@ -362,6 +369,13 @@ const onPublish = () => {
audio = {
deviceId: audioId,
};
+
+ const voice = document.getElementById('audio_voice').checked;
+ if (!voice) {
+ audio.autoGainControl = false;
+ audio.echoCancellation = false;
+ audio.noiseSuppression = false;
+ }
}
navigator.mediaDevices.getUserMedia({ video, audio })
diff --git a/internal/core/webrtc_session.go b/internal/core/webrtc_session.go
index be961448..fdd51365 100644
--- a/internal/core/webrtc_session.go
+++ b/internal/core/webrtc_session.go
@@ -61,7 +61,12 @@ func findOpusPayloadFormat(attributes []sdp.Attribute) int {
return 0
}
-func editAnswer(offer *webrtc.SessionDescription, videoBitrateStr string, audioBitrateStr string) error {
+func editAnswer(
+ offer *webrtc.SessionDescription,
+ videoBitrateStr string,
+ audioBitrateStr string,
+ audioVoice bool,
+) error {
var sd sdp.SessionDescription
err := sd.Unmarshal([]byte(offer.SDP))
if err != nil {
@@ -97,10 +102,18 @@ func editAnswer(offer *webrtc.SessionDescription, videoBitrateStr string, audioB
if pl != 0 {
for i, attr := range media.Attributes {
if attr.Key == "fmtp" && strings.HasPrefix(attr.Value, strconv.FormatInt(int64(pl), 10)+" ") {
- media.Attributes[i] = sdp.Attribute{
- Key: "fmtp",
- Value: strconv.FormatInt(int64(pl), 10) + " stereo=1;sprop-stereo=1;maxaveragebitrate=" +
- strconv.FormatUint(audioBitrate*1024, 10),
+ if audioVoice {
+ media.Attributes[i] = sdp.Attribute{
+ Key: "fmtp",
+ Value: strconv.FormatInt(int64(pl), 10) + " minptime=10;useinbandfec=1;maxaveragebitrate=" +
+ strconv.FormatUint(audioBitrate*1024, 10),
+ }
+ } else {
+ media.Attributes[i] = sdp.Attribute{
+ Key: "fmtp",
+ Value: strconv.FormatInt(int64(pl), 10) + " stereo=1;sprop-stereo=1;maxaveragebitrate=" +
+ strconv.FormatUint(audioBitrate*1024, 10),
+ }
}
}
}
@@ -368,7 +381,7 @@ func (s *webRTCSession) runPublish() (int, error) {
tmp := pc.LocalDescription()
answer = *tmp
- err = editAnswer(&answer, s.req.videoBitrate, s.req.audioBitrate)
+ err = editAnswer(&answer, s.req.videoBitrate, s.req.audioBitrate, s.req.audioVoice)
if err != nil {
return http.StatusBadRequest, err
}