revid: added metadata to audio mts streams

This commit is contained in:
Trek H 2019-06-05 15:08:47 +09:30
parent bea747085f
commit 7b4daed4a6
2 changed files with 37 additions and 25 deletions

View File

@ -92,7 +92,7 @@ func NewAudioDevice(cfg *AudioConfig, l Logger) (*AudioDevice, error) {
// Open the requested audio device. // Open the requested audio device.
err := a.open() err := a.open()
if err != nil { if err != nil {
a.l.Log(logger.Error, "failed to open audio device", "error", err.Error()) a.l.Log(logger.Error, pkg+"failed to open audio device", "error", err.Error())
return nil, errors.New("failed to open audio device") return nil, errors.New("failed to open audio device")
} }
@ -100,7 +100,7 @@ func NewAudioDevice(cfg *AudioConfig, l Logger) (*AudioDevice, error) {
a.ab = a.dev.NewBufferDuration(time.Duration(a.RecPeriod * float64(time.Second))) a.ab = a.dev.NewBufferDuration(time.Duration(a.RecPeriod * float64(time.Second)))
cs := (float64((len(a.ab.Data)/a.dev.BufferFormat().Channels)*a.Channels) / float64(a.dev.BufferFormat().Rate)) * float64(a.SampleRate) cs := (float64((len(a.ab.Data)/a.dev.BufferFormat().Channels)*a.Channels) / float64(a.dev.BufferFormat().Rate)) * float64(a.SampleRate)
if cs < 1 { if cs < 1 {
a.l.Log(logger.Error, "given AudioConfig parameters are too small", "error", err.Error()) a.l.Log(logger.Error, pkg+"given AudioConfig parameters are too small", "error", err.Error())
return nil, errors.New("given AudioConfig parameters are too small") return nil, errors.New("given AudioConfig parameters are too small")
} }
if a.Codec == ADPCM { if a.Codec == ADPCM {
@ -135,7 +135,6 @@ func (a *AudioDevice) Start() error {
default: default:
return errors.New("invalid mode") return errors.New("invalid mode")
} }
return nil
} }
// Stop will stop recording audio and close the device. // Stop will stop recording audio and close the device.
@ -155,21 +154,21 @@ func (a *AudioDevice) ChunkSize() int {
func (a *AudioDevice) open() error { func (a *AudioDevice) open() error {
// Close any existing device. // Close any existing device.
if a.dev != nil { if a.dev != nil {
a.l.Log(logger.Debug, "closing device", "source", a.source) a.l.Log(logger.Debug, pkg+"closing device", "source", a.source)
a.dev.Close() a.dev.Close()
a.dev = nil a.dev = nil
} }
// Open sound card and open recording device. // Open sound card and open recording device.
a.l.Log(logger.Debug, "opening sound card") a.l.Log(logger.Debug, pkg+"opening sound card")
cards, err := alsa.OpenCards() cards, err := alsa.OpenCards()
if err != nil { if err != nil {
a.l.Log(logger.Debug, "failed to open sound card") a.l.Log(logger.Debug, pkg+"failed to open sound card")
return err return err
} }
defer alsa.CloseCards(cards) defer alsa.CloseCards(cards)
a.l.Log(logger.Debug, "finding audio device") a.l.Log(logger.Debug, pkg+"finding audio device")
for _, card := range cards { for _, card := range cards {
devices, err := card.Devices() devices, err := card.Devices()
if err != nil { if err != nil {
@ -186,14 +185,14 @@ func (a *AudioDevice) open() error {
} }
} }
if a.dev == nil { if a.dev == nil {
a.l.Log(logger.Debug, "failed to find audio device") a.l.Log(logger.Debug, pkg+"failed to find audio device")
return errors.New("no audio device found") return errors.New("no audio device found")
} }
a.l.Log(logger.Debug, "opening audio device", "source", a.dev.Title) a.l.Log(logger.Debug, pkg+"opening audio device", "source", a.dev.Title)
err = a.dev.Open() err = a.dev.Open()
if err != nil { if err != nil {
a.l.Log(logger.Debug, "failed to open audio device") a.l.Log(logger.Debug, pkg+"failed to open audio device")
return err return err
} }
@ -218,19 +217,19 @@ func (a *AudioDevice) open() error {
_, err = a.dev.NegotiateRate(Rates[i]) _, err = a.dev.NegotiateRate(Rates[i])
if err == nil { if err == nil {
foundRate = true foundRate = true
a.l.Log(logger.Debug, "Sample rate set", "rate", Rates[i]) a.l.Log(logger.Debug, pkg+"Sample rate set", "rate", Rates[i])
} }
} }
} }
// If no easily divisible rate is found, then use the default rate. // If no easily divisible rate is found, then use the default rate.
if !foundRate { if !foundRate {
a.l.Log(logger.Warning, "Unable to sample at requested rate, default used.", "rateRequested", a.SampleRate) a.l.Log(logger.Warning, pkg+"Unable to sample at requested rate, default used.", "rateRequested", a.SampleRate)
_, err = a.dev.NegotiateRate(defaultSampleRate) _, err = a.dev.NegotiateRate(defaultSampleRate)
if err != nil { if err != nil {
return err return err
} }
a.l.Log(logger.Debug, "Sample rate set", "rate", defaultSampleRate) a.l.Log(logger.Debug, pkg+"Sample rate set", "rate", defaultSampleRate)
} }
var aFmt alsa.FormatType var aFmt alsa.FormatType
@ -256,7 +255,7 @@ func (a *AudioDevice) open() error {
if err = a.dev.Prepare(); err != nil { if err = a.dev.Prepare(); err != nil {
return err return err
} }
a.l.Log(logger.Debug, "Successfully negotiated ALSA params") a.l.Log(logger.Debug, pkg+"Successfully negotiated ALSA params")
return nil return nil
} }
@ -274,7 +273,7 @@ func (a *AudioDevice) input() {
continue continue
case stopped: case stopped:
if a.dev != nil { if a.dev != nil {
a.l.Log(logger.Debug, "closing audio device", "source", a.source) a.l.Log(logger.Debug, pkg+"closing audio device", "source", a.source)
a.dev.Close() a.dev.Close()
a.dev = nil a.dev = nil
} }
@ -282,13 +281,13 @@ func (a *AudioDevice) input() {
} }
// Read from audio device. // Read from audio device.
a.l.Log(logger.Debug, "recording audio for period", "seconds", a.RecPeriod) a.l.Log(logger.Debug, pkg+"recording audio for period", "seconds", a.RecPeriod)
err := a.dev.Read(a.ab.Data) err := a.dev.Read(a.ab.Data)
if err != nil { if err != nil {
a.l.Log(logger.Debug, "read failed", "error", err.Error()) a.l.Log(logger.Debug, pkg+"read failed", "error", err.Error())
err = a.open() // re-open err = a.open() // re-open
if err != nil { if err != nil {
a.l.Log(logger.Fatal, "reopening device failed", "error", err.Error()) a.l.Log(logger.Fatal, pkg+"reopening device failed", "error", err.Error())
return return
} }
continue continue
@ -302,11 +301,11 @@ func (a *AudioDevice) input() {
n, err := a.rb.Write(toWrite.Data) n, err := a.rb.Write(toWrite.Data)
switch err { switch err {
case nil: case nil:
a.l.Log(logger.Debug, "wrote audio to ringbuffer", "length", n) a.l.Log(logger.Debug, pkg+"wrote audio to ringbuffer", "length", n)
case ring.ErrDropped: case ring.ErrDropped:
a.l.Log(logger.Warning, "old audio data overwritten") a.l.Log(logger.Warning, pkg+"old audio data overwritten")
default: default:
a.l.Log(logger.Error, "unexpected ringbuffer error", "error", err.Error()) a.l.Log(logger.Error, pkg+"unexpected ringbuffer error", "error", err.Error())
return return
} }
} }
@ -354,7 +353,7 @@ func (a *AudioDevice) formatBuffer() alsa.Buffer {
if a.ab.Format.Channels == 2 && a.Channels == 1 { if a.ab.Format.Channels == 2 && a.Channels == 1 {
formatted.Data, err = pcm.StereoToMono(a.ab) formatted.Data, err = pcm.StereoToMono(a.ab)
if err != nil { if err != nil {
a.l.Log(logger.Fatal, "channel conversion failed", "error", err.Error()) a.l.Log(logger.Fatal, pkg+"channel conversion failed", "error", err.Error())
} }
} }
} }
@ -363,7 +362,7 @@ func (a *AudioDevice) formatBuffer() alsa.Buffer {
// Convert rate. // Convert rate.
formatted.Data, err = pcm.Resample(formatted, a.SampleRate) formatted.Data, err = pcm.Resample(formatted, a.SampleRate)
if err != nil { if err != nil {
a.l.Log(logger.Fatal, "rate conversion failed", "error", err.Error()) a.l.Log(logger.Fatal, pkg+"rate conversion failed", "error", err.Error())
} }
} }
@ -374,11 +373,11 @@ func (a *AudioDevice) formatBuffer() alsa.Buffer {
enc := adpcm.NewEncoder(b) enc := adpcm.NewEncoder(b)
_, err = enc.Write(formatted.Data) _, err = enc.Write(formatted.Data)
if err != nil { if err != nil {
a.l.Log(logger.Fatal, "unable to encode", "error", err.Error()) a.l.Log(logger.Fatal, pkg+"unable to encode", "error", err.Error())
} }
formatted.Data = b.Bytes() formatted.Data = b.Bytes()
default: default:
a.l.Log(logger.Error, "codec conversion failed, audio has remained original codec", "error", err.Error()) a.l.Log(logger.Error, pkg+"unhandled audio codec")
} }
return formatted return formatted

View File

@ -635,6 +635,19 @@ func (r *Revid) startAudioDevice() (func() error, error) {
BitDepth: r.config.BitDepth, BitDepth: r.config.BitDepth,
Codec: r.config.InputCodec, Codec: r.config.InputCodec,
} }
mts.Meta.Add("sampleRate", strconv.Itoa(r.config.SampleRate))
mts.Meta.Add("channels", strconv.Itoa(r.config.Channels))
mts.Meta.Add("period", fmt.Sprintf("%.6f", r.config.RecPeriod))
mts.Meta.Add("bitDepth", strconv.Itoa(r.config.BitDepth))
switch r.config.InputCodec {
case PCM:
mts.Meta.Add("codec", "pcm")
case ADPCM:
mts.Meta.Add("codec", "adpcm")
default:
r.config.Logger.Log(logger.Fatal, pkg+"no audio codec set in config")
}
ai, err := NewAudioDevice(ac, r.config.Logger) ai, err := NewAudioDevice(ac, r.config.Logger)
if err != nil { if err != nil {
r.config.Logger.Log(logger.Fatal, pkg+"failed to create audio device", "error", err.Error()) r.config.Logger.Log(logger.Fatal, pkg+"failed to create audio device", "error", err.Error())