mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
trying stereo audio!
This commit is contained in:
@@ -19,8 +19,6 @@ fi
|
|||||||
: "${AUDIO_PUBLISH_URL:?AUDIO_PUBLISH_URL not set in ${ENV_FILE}}"
|
: "${AUDIO_PUBLISH_URL:?AUDIO_PUBLISH_URL not set in ${ENV_FILE}}"
|
||||||
|
|
||||||
AUDIO_DEVICE="${AUDIO_DEVICE:-hw:0,0}"
|
AUDIO_DEVICE="${AUDIO_DEVICE:-hw:0,0}"
|
||||||
AUDIO_RATE="${AUDIO_RATE:-48000}"
|
|
||||||
AUDIO_CHANNELS="${AUDIO_CHANNELS:-2}"
|
|
||||||
|
|
||||||
if [[ -n "${FFMPEG_BIN:-}" ]]; then
|
if [[ -n "${FFMPEG_BIN:-}" ]]; then
|
||||||
FFMPEG_BIN_PATH="$FFMPEG_BIN"
|
FFMPEG_BIN_PATH="$FFMPEG_BIN"
|
||||||
@@ -32,27 +30,50 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
run_pipeline() {
|
run_pipeline() {
|
||||||
arecord -D "${AUDIO_DEVICE}" -f S32_LE -c "${AUDIO_CHANNELS}" -r "${AUDIO_RATE}" -B 65536 -F 2048 -q -t raw \
|
local ffmpeg_args=(
|
||||||
| "${FFMPEG_BIN_PATH}" \
|
-hide_banner
|
||||||
-hide_banner \
|
-loglevel warning
|
||||||
-loglevel warning \
|
-fflags nobuffer
|
||||||
-fflags nobuffer \
|
-rtbufsize 0
|
||||||
-rtbufsize 0 \
|
-thread_queue_size 4096
|
||||||
-thread_queue_size 4096 \
|
|
||||||
-f s32le \
|
# Match the raw ALSA stream exactly so ffmpeg does not guess the pipe
|
||||||
-ar "${AUDIO_RATE}" \
|
# format and so the published audio stays full-band stereo before the
|
||||||
-ac "${AUDIO_CHANNELS}" \
|
# Opus encoder sees it.
|
||||||
-i pipe:0 \
|
-f s32le
|
||||||
-af "aresample=16000,pan=mono|c0=0.5*FL+0.5*FR,volume=25dB" \
|
-ar 48000
|
||||||
-c:a libopus \
|
-ac 2
|
||||||
-b:a 24000 \
|
-i pipe:0
|
||||||
-ar:a 16000 \
|
|
||||||
-ac:a 1 \
|
# Keep the known-required microphone boost, but remove the old
|
||||||
-application lowdelay \
|
# resample/downmix filter. That old filter threw away stereo and
|
||||||
-frame_duration 20 \
|
# limited the stream to narrow 16 kHz mono before encoding.
|
||||||
-compression_level 0 \
|
-af "volume=25dB"
|
||||||
-f mpegts \
|
|
||||||
|
# Opus supports up to 510 kbps. Using that ceiling keeps the stream at
|
||||||
|
# the highest practical quality browsers and MediaMTX can carry without
|
||||||
|
# trying to push raw PCM through the live path.
|
||||||
|
-c:a libopus
|
||||||
|
-b:a 510000
|
||||||
|
-ar:a 48000
|
||||||
|
-ac:a 2
|
||||||
|
|
||||||
|
# Use the audio profile for quality. Latency is still controlled by the
|
||||||
|
# 20 ms Opus frame size and the low-buffering capture/publish options
|
||||||
|
# around the encoder.
|
||||||
|
-application audio
|
||||||
|
-frame_duration 20
|
||||||
|
-compression_level 0
|
||||||
|
-f mpegts
|
||||||
"${AUDIO_PUBLISH_URL}"
|
"${AUDIO_PUBLISH_URL}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# The Google Voice HAT microphone path is intentionally fixed instead of
|
||||||
|
# configurable. The previous env-driven sample rate/channel knobs made it
|
||||||
|
# easy for the rover config and the actual ffmpeg pipeline to drift apart,
|
||||||
|
# while the hardware path we install is always 48 kHz stereo capture.
|
||||||
|
arecord -D "${AUDIO_DEVICE}" -f S32_LE -c 2 -r 48000 -B 65536 -F 2048 -q -t raw \
|
||||||
|
| "${FFMPEG_BIN_PATH}" "${ffmpeg_args[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
trap 'kill 0 2>/dev/null' EXIT INT TERM
|
trap 'kill 0 2>/dev/null' EXIT INT TERM
|
||||||
|
|||||||
@@ -321,8 +321,6 @@ VIDEO_BITRATE=2000000
|
|||||||
AUDIO_ENABLE=0
|
AUDIO_ENABLE=0
|
||||||
AUDIO_DEVICE=hw:0,0
|
AUDIO_DEVICE=hw:0,0
|
||||||
AUDIO_PLAYBACK_DEVICE=forward
|
AUDIO_PLAYBACK_DEVICE=forward
|
||||||
AUDIO_RATE=48000
|
|
||||||
AUDIO_CHANNELS=2
|
|
||||||
ENV
|
ENV
|
||||||
chown roverd:roverd /var/lib/roverd/video.env
|
chown roverd:roverd /var/lib/roverd/video.env
|
||||||
chmod 0640 /var/lib/roverd/video.env
|
chmod 0640 /var/lib/roverd/video.env
|
||||||
|
|||||||
@@ -59,9 +59,6 @@ type AudioConfig struct {
|
|||||||
CaptureEnabled bool `yaml:"captureEnabled" json:"captureEnabled"`
|
CaptureEnabled bool `yaml:"captureEnabled" json:"captureEnabled"`
|
||||||
CaptureDevice string `yaml:"captureDevice" json:"captureDevice,omitempty"`
|
CaptureDevice string `yaml:"captureDevice" json:"captureDevice,omitempty"`
|
||||||
PlaybackDevice string `yaml:"playbackDevice" json:"playbackDevice,omitempty"`
|
PlaybackDevice string `yaml:"playbackDevice" json:"playbackDevice,omitempty"`
|
||||||
SampleRate int `yaml:"sampleRate" json:"sampleRate,omitempty"`
|
|
||||||
Channels int `yaml:"channels" json:"channels,omitempty"`
|
|
||||||
Bitrate int `yaml:"bitrate" json:"bitrate,omitempty"`
|
|
||||||
TTSEnabled bool `yaml:"ttsEnabled" json:"ttsEnabled"`
|
TTSEnabled bool `yaml:"ttsEnabled" json:"ttsEnabled"`
|
||||||
DefaultEngine string `yaml:"defaultEngine" json:"defaultEngine,omitempty"`
|
DefaultEngine string `yaml:"defaultEngine" json:"defaultEngine,omitempty"`
|
||||||
DefaultVoice string `yaml:"defaultVoice" json:"defaultVoice,omitempty"`
|
DefaultVoice string `yaml:"defaultVoice" json:"defaultVoice,omitempty"`
|
||||||
@@ -199,9 +196,6 @@ func LoadConfig(path string) (*Config, error) {
|
|||||||
CaptureEnabled: false,
|
CaptureEnabled: false,
|
||||||
CaptureDevice: "rovermic",
|
CaptureDevice: "rovermic",
|
||||||
PlaybackDevice: "forward",
|
PlaybackDevice: "forward",
|
||||||
SampleRate: 48000,
|
|
||||||
Channels: 2,
|
|
||||||
Bitrate: 24000,
|
|
||||||
TTSEnabled: false,
|
TTSEnabled: false,
|
||||||
DefaultEngine: "flite",
|
DefaultEngine: "flite",
|
||||||
DefaultVoice: "rms",
|
DefaultVoice: "rms",
|
||||||
@@ -364,15 +358,6 @@ func validateAudioConfig(cfg *AudioConfig) {
|
|||||||
if cfg.PlaybackDevice == "" || cfg.PlaybackDevice == "default" {
|
if cfg.PlaybackDevice == "" || cfg.PlaybackDevice == "default" {
|
||||||
cfg.PlaybackDevice = "forward"
|
cfg.PlaybackDevice = "forward"
|
||||||
}
|
}
|
||||||
if cfg.SampleRate <= 0 {
|
|
||||||
cfg.SampleRate = 48000
|
|
||||||
}
|
|
||||||
if cfg.Channels <= 0 {
|
|
||||||
cfg.Channels = 2
|
|
||||||
}
|
|
||||||
if cfg.Bitrate <= 0 {
|
|
||||||
cfg.Bitrate = 64000
|
|
||||||
}
|
|
||||||
if cfg.DefaultEngine == "" {
|
if cfg.DefaultEngine == "" {
|
||||||
cfg.DefaultEngine = "flite"
|
cfg.DefaultEngine = "flite"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ func UpdatePublisherEnv(media MediaConfig, audio AudioConfig) error {
|
|||||||
if audioDevice == "" || audioDevice == "rovermic" {
|
if audioDevice == "" || audioDevice == "rovermic" {
|
||||||
audioDevice = "hw:0,0"
|
audioDevice = "hw:0,0"
|
||||||
}
|
}
|
||||||
if audio.SampleRate <= 0 {
|
|
||||||
audio.SampleRate = 48000
|
|
||||||
}
|
|
||||||
if audio.Channels <= 0 {
|
|
||||||
audio.Channels = 2
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&buf, "AUDIO_ENABLE=%d\n", boolToInt(audio.CaptureEnabled))
|
fmt.Fprintf(&buf, "AUDIO_ENABLE=%d\n", boolToInt(audio.CaptureEnabled))
|
||||||
fmt.Fprintf(&buf, "AUDIO_DEVICE=%s\n", audioDevice)
|
fmt.Fprintf(&buf, "AUDIO_DEVICE=%s\n", audioDevice)
|
||||||
playbackDevice := audio.PlaybackDevice
|
playbackDevice := audio.PlaybackDevice
|
||||||
@@ -58,8 +52,6 @@ func UpdatePublisherEnv(media MediaConfig, audio AudioConfig) error {
|
|||||||
playbackDevice = "forward"
|
playbackDevice = "forward"
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&buf, "AUDIO_PLAYBACK_DEVICE=%s\n", playbackDevice)
|
fmt.Fprintf(&buf, "AUDIO_PLAYBACK_DEVICE=%s\n", playbackDevice)
|
||||||
fmt.Fprintf(&buf, "AUDIO_RATE=%d\n", audio.SampleRate)
|
|
||||||
fmt.Fprintf(&buf, "AUDIO_CHANNELS=%d\n", audio.Channels)
|
|
||||||
if err := os.WriteFile(publisherEnvPath, buf.Bytes(), 0o640); err != nil {
|
if err := os.WriteFile(publisherEnvPath, buf.Bytes(), 0o640); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ audio:
|
|||||||
captureEnabled: false
|
captureEnabled: false
|
||||||
captureDevice: hw:0,0
|
captureDevice: hw:0,0
|
||||||
playbackDevice: forward
|
playbackDevice: forward
|
||||||
sampleRate: 48000
|
|
||||||
channels: 2
|
|
||||||
bitrate: 24000
|
|
||||||
ttsEnabled: false
|
ttsEnabled: false
|
||||||
defaultEngine: flite
|
defaultEngine: flite
|
||||||
defaultVoice: rms
|
defaultVoice: rms
|
||||||
|
|||||||
Reference in New Issue
Block a user