mirror of https://bitbucket.org/ausocean/av.git
revid: added metadata to audio mts streams
This commit is contained in:
parent
bea747085f
commit
7b4daed4a6
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in New Issue