Skip to content

Instantly share code, notes, and snippets.

@kaiiak
Last active March 23, 2024 15:28
Show Gist options
  • Save kaiiak/4e5f058f4289153a525a54fbc43e756a to your computer and use it in GitHub Desktop.
Save kaiiak/4e5f058f4289153a525a54fbc43e756a to your computer and use it in GitHub Desktop.
convert mp3 to pcm with golang
package ffmpeg
import (
"errors"
"fmt"
"io"
"unsafe"
"github.com/giorgisio/goav/avcodec"
"github.com/giorgisio/goav/avformat"
"github.com/giorgisio/goav/avutil"
)
func init() {
avformat.AvRegisterAll()
}
// Mp3TransformPcm depend ffmpeg
func Mp3TransformPcm(in string, w io.Writer) error {
inCtx := avformat.AvformatAllocContext()
if avformat.AvformatOpenInput(&inCtx, in, nil, nil) < 0 {
return errors.New("open file error")
}
defer inCtx.AvformatCloseInput()
if inCtx.AvformatFindStreamInfo(nil) < 0 {
return errors.New("couldn't find stream information")
}
var audioStreamIndex = -1
for i := 0; i < len(inCtx.Streams()); i++ {
if inCtx.Streams()[i].CodecParameters().AvCodecGetType() == avformat.AVMEDIA_TYPE_AUDIO {
fmt.Println("find audio index", i)
audioStreamIndex = i
}
}
codec := avcodec.AvcodecFindDecoder(avcodec.CodecId(inCtx.AudioCodecId()))
codecCtx := codec.AvcodecAllocContext3()
defer codecCtx.AvcodecClose()
pkt := avcodec.AvPacketAlloc()
defer pkt.AvPacketUnref()
if pkt == nil {
return errors.New("packet alloc error")
}
defer pkt.AvFreePacket()
utilFrame := avutil.AvFrameAlloc()
if utilFrame == nil {
return errors.New("frame alloc error")
}
defer avutil.AvFrameFree(utilFrame)
var gotName int
var index int
for inCtx.AvReadFrame(pkt) == 0 {
if pkt.StreamIndex() == audioStreamIndex {
if codecCtx.AvcodecDecodeAudio4((*avcodec.Frame)(unsafe.Pointer(utilFrame)), &gotName, pkt) < 0 {
return errors.New("codec decode audio4 error")
}
if gotName > 0 {
if _, err := w.Write(getFramBytes(utilFrame)); err != nil {
return err
}
index++
}
}
}
return nil
}
func getFramBytes(f *avutil.Frame) []byte {
data := avutil.Data(f)
var bs = make([]byte, 0, len(data))
for i := 0; i < len(data); i++ {
bs = append(bs, *data[i])
}
return bs
}
package ffmpeg
import (
"os"
"testing"
)
func TestMp3TransformPcm(t *testing.T) {
out, err := os.Create("1.pcm")
if err != nil {
t.Fatal(err)
}
defer out.Close()
if err := Mp3TransformPcm("1.mp3", out); err != nil {
t.Fatal(err)
}
}
@kaiiak
Copy link
Author

kaiiak commented Jun 6, 2020

What's your ffmpeg version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment