godub lets you manipulate audio in an easy and elegant way. It's ported from the excellent project pydub.
There are some audio packages in the Go world, but we believe that pydub provides a better way to do stuff to audios. Therefore, here we have godub! However, due to limited time and personal ability, not all the features of pydub are supported.
- Load audio files, supports mp3/m4a/wav...
- Export/convert audio with custom configs.
- Slice an audio.
- Concatenate two or more audios.
- Repeat an audio.
- Overlay with other audios.
- Reverse an audio.
- ...
func main() {
filePath := path.Join(dataDirectory(), "code-geass.mp3")
segment, _ := godub.NewLoader().Load(filePath)
fmt.Println(segment)
buf, _ := ioutil.ReadAll()
// Load from buffer, load also accepts `io.Reader` type.
segment, _ = godub.NewLoader().Load(bytes.NewReader(buf))
fmt.Println(segment)
}
func main() {
filePath := path.Join(dataDirectory(), "code-geass.mp3")
segment, _ := godub.NewLoader().Load(filePath)
// Export as a mp3 file.
toFilePath := path.Join(dataDirectory(), "converted", "code-geass.mp3")
err := godub.NewExporter(toFilePath).
WithDstFormat("mp3").
WithBitRate(128000).
Export(segment)
if err != nil {
log.Fatal(err)
}
// Let's check it.
segment, _ = godub.NewLoader().Load(toFilePath)
fmt.Println(segment)
}
func main() {
filePath := path.Join(dataDirectory(), "code-geass.mp3")
toFilePath := path.Join(dataDirectory(), "converted", "code-geass.m4a")
w, _ := os.Create(toFilePath)
err := audio.NewConverter(w).
WithBitRate(64000).
WithDstFormat("m4a").
Convert(filePath)
if err != nil {
log.Fatal(err)
}
segment, _ := godub.NewLoader().Load(toFilePath)
fmt.Println(segment)
}
func slice() {
filePath := path.Join(dataDirectory(), "code-geass.mp3")
segment, _ := godub.NewLoader().Load(filePath)
// Slice from 0 sec to 100 secs.
slicedSegment, _ := segment.Slice(0, 100*time.Second)
// Then export it as mp3 file.
slicedPath := path.Join(dataDirectory(), "slice", "code-geass.mp3")
godub.NewExporter(slicedPath).WithDstFormat("mp3").Export(slicedSegment)
}
func main() {
filePath := path.Join(dataDirectory(), "code-geass.mp3")
segment, _ := godub.NewLoader().Load(filePath)
// Yep, you can append more than one segment.
newSeg, err := segment.Append(segment, segment)
if err != nil {
log.Fatal(err)
}
// Save the newly created audio segment as mp3 file.
newPth := path.Join(dataDirectory(), "append", "code-geass.mp3")
godub.NewExporter(newPth).WithDstFormat("mp3").WithBitRate(audio.MP3BitRatePerfect).Export(newSeg)
}
func main() {
segment, _ := godub.NewLoader().Load(path.Join(dataDirectory(), "code-geass.mp3"))
otherSegment, _ := godub.NewLoader().Load(path.Join(dataDirectory(), "ring.mp3"))
overlaidSeg, err := segment.Overlay(otherSegment, &godub.OverlayConfig{LoopToEnd: true})
if err != nil {
log.Fatal(err)
}
godub.NewExporter(destPath).WithDstFormat("wav").Export(path.Join(tmpDataDirectory(), "overlay-ring.wav"))
}
func SplitOnSilence(seg *AudioSegment, minSilenceLen int, silenceThresh Volume, keepSilence int, seekStep int) ([]*AudioSegment, [][]float32)
Args: seg - a AudioSegment object minSilenceLen - the minimum silence lenght in milliseconds on which to segment the audios silenceThresh - the threshold in dB below which everything is considered silence keepSilence - the silence in milliseconds to keep at both ends of a segment seekStep - the step in milliseconds
Returns: chunks - an array of AudioSegments timings - an array with the start and end times in seconds
Takes a AudioSegment as input and return two arrays with chunks and their timing info The timing returned is in reference to the original segment and is measured in seconds. So if you combine the chunks, the timing will reflect the segment in the original audio, not the lenght of the new chunk you've created.
func main(){
segment, _ := godub.NewLoader().Load(path.Join(dataDirectory(), "code-geass.mp3"))
//threshold := godub.NewVolumeFromRatio(segment.DBFS().ToRatio(false)*0.15, 0, false) // Setting threshold as a ratio
threshold := godub.Volume(-23) //Setting a threshold manually
chunks, timings := godub.SplitOnSilence(segment, 1000, threshold, 1000, 1)
for i := range segs {
toFilePath := path.Join(tFP, "seg-"+strconv.Itoa(i))
godub.NewExporter(toFilePath).WithDstFormat("wav").WithBitRate(8000).Export(chunks[i])
}
}
godub uses ffmpeg as its backend to support encoding, decoding and conversion.
- go-binary-pack
- Python struct
- Digital Audio - Creating a WAV (RIFF) file
- ffmpeg tutorial
- Python: manipulate raw audio data with
audioop
- ffmpeg Documentation
- Audio effects.
- As always, test test test!
godub is licensed under the MIT license. Please feel free and have fun.