Support HE-AAC, VBR modes
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
DataHoarder 2022-05-15 17:53:28 +02:00
parent 713835cd85
commit 994702105a
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
6 changed files with 82 additions and 39 deletions

View file

@ -13,15 +13,15 @@ Collection of audio utilities for decoding/encoding files and streams.
## Codecs supported
| Codec | Containers | Decoder | Analyzer | Encoder | Notes |
|:----------:|:----------------------------------------------------------------------------------------:|:-------:|:--------:|:-------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **FLAC** | [FLAC](https://xiph.org/flac/format.html), [Ogg](https://xiph.org/flac/ogg_mapping.html) | ✅ | ✅ | ✅ | Adjustable encoding compression level and block size.<br/>Decoding/encoding by [libFLAC](https://github.com/xiph/flac) via [goflac](https://git.gammaspectra.live/S.O.N.G/goflac). |
| **TTA** | [TTA](https://www.tausoft.org/en/true_audio_codec_format/) | ✅ | ✅ | ✅ | Decoding/encoding via [go-tta](https://git.gammaspectra.live/S.O.N.G/go-tta). |
| **MP3** | [MP3](http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html) | ✅ | - | ✅ | Adjustable encoding bitrate and mode.<br/>Decoding via [minimp3](https://github.com/kvark128/minimp3), encoding by [LAME](https://lame.sourceforge.io/) via [go-lame](https://github.com/viert/go-lame). |
| **Opus** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | - | ✅ | Adjustable encoding bitrate.<br/>Decoding/encoding by [libopus](https://github.com/xiph/opus) via [go-pus](https://git.gammaspectra.live/S.O.N.G/go-pus). |
| **Vorbis** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | - | ❌ | Decoding by [jfreymuth/vorbis](https://github.com/jfreymuth/vorbis) via [jfreymuth/oggvorbis](https://github.com/jfreymuth/oggvorbis). |
| **AAC** | [ADTS](https://wiki.multimedia.cx/index.php/ADTS), ADIF*, MP4** | ✅ | - | ✅ | Adjustable encoding bitrate and mode (LC, HEv2).<br/>Decoding/encoding by [FDK-AAC](https://github.com/mstorsjo/fdk-aac) via [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac).<br/>If [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac) codec is disabled, [VisualOn AAC encoder](https://github.com/gen2brain/aac-go) will be used for limited encoding support.<br/>*ADIF only supported on encoding.<br/>**MP4 only supported on encoding, and fragmented MP4 currently. |
| **ALAC** | MP4* | ✅ | ✅ | ✅ | Decoding/encoding by [libalac](https://git.gammaspectra.live/S.O.N.G/alac) via [go-alac](https://git.gammaspectra.live/S.O.N.G/go-alac).<br/>Disabled by default.<br/>*MP4 encoding only supported on fragmented MP4 currently. |
| Codec | Containers | Decoder | Analyzer | Encoder | Notes |
|:----------:|:----------------------------------------------------------------------------------------:|:-------:|:--------:|:-------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **FLAC** | [FLAC](https://xiph.org/flac/format.html), [Ogg](https://xiph.org/flac/ogg_mapping.html) | ✅ | ✅ | ✅ | Adjustable encoding compression level and block size.<br/>Decoding/encoding by [libFLAC](https://github.com/xiph/flac) via [goflac](https://git.gammaspectra.live/S.O.N.G/goflac). |
| **TTA** | [TTA](https://www.tausoft.org/en/true_audio_codec_format/) | ✅ | ✅ | ✅ | Decoding/encoding via [go-tta](https://git.gammaspectra.live/S.O.N.G/go-tta). |
| **MP3** | [MP3](http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html) | ✅ | - | ✅ | Adjustable encoding bitrate and mode.<br/>Decoding via [minimp3](https://github.com/kvark128/minimp3), encoding by [LAME](https://lame.sourceforge.io/) via [go-lame](https://github.com/viert/go-lame). |
| **Opus** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | - | ✅ | Adjustable encoding bitrate.<br/>Decoding/encoding by [libopus](https://github.com/xiph/opus) via [go-pus](https://git.gammaspectra.live/S.O.N.G/go-pus). |
| **Vorbis** | [Ogg](https://www.xiph.org/ogg/doc/framing.html) | ✅ | - | ❌ | Decoding by [jfreymuth/vorbis](https://github.com/jfreymuth/vorbis) via [jfreymuth/oggvorbis](https://github.com/jfreymuth/oggvorbis). |
| **AAC** | [ADTS](https://wiki.multimedia.cx/index.php/ADTS), ADIF*, MP4** | ✅ | - | ✅ | Adjustable encoding bitrate and mode (LC, HEv1, HEv2).<br/>Decoding/encoding by [FDK-AAC](https://github.com/mstorsjo/fdk-aac) via [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac).<br/>If [go-fdkaac](https://git.gammaspectra.live/S.O.N.G/go-fdkaac) codec is disabled, [VisualOn AAC encoder](https://github.com/gen2brain/aac-go) will be used for limited encoding support.<br/>*ADIF only supported on encoding.<br/>**MP4 only supported on encoding, and fragmented MP4 currently. |
| **ALAC** | MP4* | ✅ | ✅ | ✅ | Decoding/encoding by [libalac](https://git.gammaspectra.live/S.O.N.G/alac) via [go-alac](https://git.gammaspectra.live/S.O.N.G/go-alac).<br/>Disabled by default.<br/>*MP4 encoding only supported on fragmented MP4 currently. |
## Container packetizers supported

View file

@ -202,41 +202,72 @@ func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
}
func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[string]interface{}) error {
var bitrate = 128
var isHEv2 bool
var bitrate = 128 * 1024
var codecMode = 0 //0 = LC, 1 = HE, 2 = HEv2
var afterburner = 1
var format = "adts"
if options != nil {
var val interface{}
var ok bool
var intVal int
var int64Val int64
var strVal string
var boolVal bool
if val, ok = options["bitrate"]; ok {
if strVal, ok = val.(string); ok {
switch strVal {
case "320k":
bitrate = 320
bitrate = 320 * 1024
case "256k":
bitrate = 256
bitrate = 256 * 1024
case "192k":
bitrate = 192
bitrate = 192 * 1024
case "128k":
bitrate = 128
bitrate = 128 * 1024
case "vbr1":
bitrate = -1
codecMode = 2
case "vbr2":
bitrate = -2
codecMode = 1
case "vbr3":
bitrate = -3
codecMode = 0
case "vbr4":
bitrate = -4
codecMode = 0
case "vbr5":
bitrate = -5
codecMode = 0
default:
return fmt.Errorf("unknown setting bitrate=%s", strVal)
}
} else if intVal, ok = val.(int); ok {
bitrate = intVal
bitrate = intVal * 1024
} else if int64Val, ok = val.(int64); ok {
bitrate = int(int64Val) * 1024
}
}
if val, ok = options["afterburner"]; ok {
if boolVal, ok = val.(bool); ok {
if boolVal {
afterburner = 1
} else {
afterburner = 0
}
}
}
if val, ok = options["mode"]; ok {
if strVal, ok = val.(string); ok {
switch strVal {
case "lc":
isHEv2 = false
codecMode = 0
case "he", "hev1":
codecMode = 1
case "hev2":
isHEv2 = true
codecMode = 2
default:
return fmt.Errorf("unknown setting mode=%s", strVal)
@ -263,13 +294,18 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
}
encoder := fdkaac.NewAacEncoder()
if isHEv2 {
err := encoder.InitHEv2(source.Channels, source.SampleRate, bitrate*1024, muxingMode)
if codecMode == 0 {
err := encoder.InitLc(source.Channels, source.SampleRate, bitrate, muxingMode, afterburner)
if err != nil {
return err
}
} else if codecMode == 1 {
err := encoder.InitHE(source.Channels, source.SampleRate, bitrate, muxingMode, afterburner)
if err != nil {
return err
}
} else {
err := encoder.InitLc(source.Channels, source.SampleRate, bitrate*1024, muxingMode)
err := encoder.InitHEv2(source.Channels, source.SampleRate, bitrate, muxingMode, afterburner)
if err != nil {
return err
}
@ -285,7 +321,9 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
trak := init.Moov.Trak
objType := aac_adts.AAClc
if isHEv2 {
if codecMode == 1 {
objType = aac_adts.HEAACv1
} else if codecMode == 2 {
objType = aac_adts.HEAACv2
}
@ -480,5 +518,6 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
}
func (f Format) Identify(peek []byte, extension string) bool {
//TODO: add .m4a/mp4 detection
return extension == "aac" || extension == "adts"
}

View file

@ -28,7 +28,6 @@ func (f Format) Description() string {
func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[string]interface{}) error {
var bitrate = 128
var isHEv2 bool
if options != nil {
var val interface{}
@ -54,19 +53,6 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
bitrate = intVal
}
}
if val, ok = options["mode"]; ok {
if strVal, ok = val.(string); ok {
switch strVal {
case "lc":
isHEv2 = false
case "hev2":
isHEv2 = true
default:
return fmt.Errorf("unknown setting mode=%s", strVal)
}
}
}
if val, ok = options["format"]; ok {
if strVal, ok = val.(string); ok {
if strVal != "adts" {

View file

@ -42,6 +42,24 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
case "v3":
vbr = true
bitrate = 3
case "v4":
vbr = true
bitrate = 3
case "v5":
vbr = true
bitrate = 3
case "v6":
vbr = true
bitrate = 3
case "v7":
vbr = true
bitrate = 3
case "v8":
vbr = true
bitrate = 3
case "v9":
vbr = true
bitrate = 3
case "320k":
vbr = false
bitrate = 320

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.18
require (
git.gammaspectra.live/S.O.N.G/go-alac v0.0.0-20220421115623-d0b3bfe57e0f
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220418202343-73a167e76255
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220421165127-c4b73b260d94
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220515153411-ab93196cf14c
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6
git.gammaspectra.live/S.O.N.G/goflac v0.0.0-20220417181802-3057bde44c07

4
go.sum
View file

@ -2,8 +2,8 @@ git.gammaspectra.live/S.O.N.G/go-alac v0.0.0-20220421115623-d0b3bfe57e0f h1:CxN7
git.gammaspectra.live/S.O.N.G/go-alac v0.0.0-20220421115623-d0b3bfe57e0f/go.mod h1:f1+h7KOnuM9zcEQp7ri4UaVvgX4m1NFFIXgReIyjGMA=
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220418202343-73a167e76255 h1:BWRx2ZFyhp5+rsXhdDZtk5Gld+L44lxlN9ASqB9Oj0M=
git.gammaspectra.live/S.O.N.G/go-ebur128 v0.0.0-20220418202343-73a167e76255/go.mod h1:5H4eVW9uknpn8REFr+C3ejhvXdncgm/pbGqKGC43gFY=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220421165127-c4b73b260d94 h1:gD6lOyQwwuyJilwbLC8lAEWpUSZvndJsUGwxxDatCAE=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220421165127-c4b73b260d94/go.mod h1:pkWt//S9hLVEQaJDPu/cHHPk8vPpo/0+zHy0me4LIP4=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220515153411-ab93196cf14c h1:+QTXccGE6THWHcHkRL9NtBT6NT1m5YYgfVaI/L29S54=
git.gammaspectra.live/S.O.N.G/go-fdkaac v0.0.0-20220515153411-ab93196cf14c/go.mod h1:pkWt//S9hLVEQaJDPu/cHHPk8vPpo/0+zHy0me4LIP4=
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba h1:JEaxCVgdr3XXAuDCPAx7ttLFZaaHzTEzG+oRnVUtUKU=
git.gammaspectra.live/S.O.N.G/go-pus v0.0.0-20220227175608-6cc027f24dba/go.mod h1:vkoHSHVM9p6vAUmXAik0gvaLcIfiQYrD6bQqVpOulUk=
git.gammaspectra.live/S.O.N.G/go-tta v0.2.1-0.20220226150007-096de1072bd6 h1:ITVVisbHPnUclp3PBkCbXFeBhOCBcOjPdgjJ9wRH3TI=