8k双声道的pcmu格式重采样44.1kHz并转码aac格式例子
src : 其中adts包是给aac填充头部的,这里就没给了。
package main
import(
"github.com/ailumiyana/goav-incr/goav/avcodec"
"github.com/ailumiyana/goav-incr/goav/avutil"
"github.com/ailumiyana/goav-incr/goav/avfilter"
"unsafe"
"os"
"io/ioutil"
"log"
"strconv"
"adts"
)
func main() {
avutil.AvLogSetLevel(avutil.AV_LOG_TRACE)
//decoder
pkt := avcodec.AvPacketAlloc()
if pkt == nil {
log.Panic("AvPacketAlloc failed.")
}
codec := avcodec.AvcodecFindDecoder(avcodec.CodecId(avcodec.AV_CODEC_ID_PCM_MULAW))
if codec == nil {
log.Panic("AvcodecFindDecoder failed.")
}
context := codec.AvcodecAllocContext3()
if context == nil {
log.Panic("AvcodecAllocContext3 failed.")
}
frame := avutil.AvFrameAlloc()
if frame == nil {
log.Panic("AvFrameAlloc failed.")
}
//设置通道数
context.SetAudioDecodeParamsTest(2)
context.AvcodecOpen2(codec, nil)
//encoder
codec_enc := avcodec.AvcodecFindEncoder(avcodec.CodecId(avcodec.AV_CODEC_ID_AAC))
if codec_enc == nil {
log.Panic("AvcodecFindEncoder failed.")
}
pkt_enc := avcodec.AvPacketAlloc()
if pkt_enc == nil {
log.Panic("AvPacketAlloc failed.")
}
context_enc := codec_enc.AvcodecAllocContext3()
if context_enc == nil {
log.Panic("AvcodecAllocContext3 failed.")
}
context_enc.SetAudioEncodeParams(128000, 44100, "stereo", avcodec.AV_SAMPLE_FMT_FLTP)
err := context_enc.AvcodecOpen2(codec_enc, nil)
if err < 0 {
log.Panic("AvcodecOpen2 failed.")
}
//filter
graph := avfilter.AvfilterGraphAlloc()
if graph == nil {
log.Fatal("AvfilterGraphAlloc Failed.")
}
inputs := avfilter.AvfilterInoutAlloc()
outputs := avfilter.AvfilterInoutAlloc()
if inputs == nil || outputs == nil {
log.Fatal("AvfilterInoutAlloc Failed.")
}
defer avfilter.AvfilterInoutFree(inputs)
defer avfilter.AvfilterInoutFree(outputs)
var buffersrc *avfilter.Filter
var buffersink *avfilter.Filter
buffersrc = avfilter.AvfilterGetByName("abuffer")
buffersink = avfilter.AvfilterGetByName("abuffersink")
if buffersink == nil || buffersrc == nil {
log.Panic("AvfilterGetByName Failed.")
}
ret := graph.AvfilterGraphParse2("aresample=44100,aformat=sample_fmts=fltp:channel_layouts=stereo,asetnsamples=1024", &inputs, &outputs)
if ret < 0 {
log.Panic("AvfilterInoutAlloc Failed des : ", avutil.ErrorFromCode(ret))
}
var ins []*avfilter.Context
var outs []*avfilter.Context
var frames []*avutil.Frame
// inputs
index := 0
for cur := inputs; cur != nil; cur = cur.Next() {
var in *avfilter.Context
inName := "in" + strconv.Itoa(index)
ret = avfilter.AvfilterGraphCreateFilter(&in, buffersrc, inName, "sample_rate=8000:time_base=1/8000:sample_fmt=s16:channel_layout=stereo", 0, graph)
if ret < 0 {
log.Panic("AvfilterGraphCreateFilter Failed des : ", avutil.ErrorFromCode(ret))
}
ins = append(ins, in)
ret = avfilter.AvfilterLink(ins[index], 0, cur.FilterContext(), cur.PadIdx())
if ret < 0 {
log.Panic("AvfilterLink Failed des : ", avutil.ErrorFromCode(ret))
}
index++
}
// outputs
index = 0
for cur := outputs; cur != nil; cur = cur.Next() {
var out *avfilter.Context
outName := "out" + strconv.Itoa(index)
ret = avfilter.AvfilterGraphCreateFilter(&out, buffersink, outName, "", 0, graph)
if ret < 0 {
log.Panic("AvfilterGraphCreateFilter Failed des : ", avutil.ErrorFromCode(ret))
}
outs = append(outs, out)
ret = avfilter.AvfilterLink(cur.FilterContext(), cur.PadIdx(), outs[index], 0)
if ret < 0 {
log.Panic("AvfilterLink Failed des : ", avutil.ErrorFromCode(ret))
}
index++
f := avutil.AvFrameAlloc()
if f == nil {
log.Panic("AvFrameAlloc failed.")
}
frames = append(frames, f)
}
ret = graph.AvfilterGraphConfig(0)
if ret < 0 {
log.Panic("AvfilterGraphConfig Failed des : ", avutil.ErrorFromCode(ret))
}
//input pcm file
data, errr := ioutil.ReadFile("ilem8kmulaw.pcm")
if errr != nil {
log.Panic("File reading error", err)
}
l := len(data)
//parser := make([]byte, 160)
offset := -160
//out aac file
file, errr := os.Create("./out.aac")
if errr != nil {
log.Panic("Error Reading")
}
defer file.Close()
//handle
apts := int64(0)
for offset + 160 < l {
offset+=160
pkt.AvPacketFromData(data[offset:offset+160], 160)
ret := context.AvcodecSendPacket(pkt)
if ret < 0 {
log.Println("AvcodecSendPacket err ", avutil.ErrorFromCode(ret))
}
ret = context.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(frame)))
if ret < 0 {
log.Println("AvcodecReceiveFrame err ", avutil.ErrorFromCode(ret))
}
if ret == 0 {
apts += 160
frame.SetPts(apts)
frame.SetSampleRate(8000)
ret := avfilter.AvBuffersrcAddFrame(ins[0], (*avfilter.Frame)(unsafe.Pointer(frame)))
if ret < 0 {
log.Println("AvBuffersrcAddFrame error :", avutil.ErrorFromCode(ret))
}
log.Println("---------")
ret = avfilter.AvBufferSinkGetFrame(outs[0], (*avfilter.Frame)(unsafe.Pointer(frames[0])))
if ret == -11 {
log.Println("AvBufferSinkGetFrame Failed des : ", ret, avutil.ErrorFromCode(ret))
avutil.AvFrameUnref(frame)
continue
}
if frames[0] != nil {
ret = context_enc.AvcodecSendFrame((*avcodec.Frame)(unsafe.Pointer(frames[0])))
if ret < 0 {
log.Panic("AvcodecSendFrame err ", avutil.ErrorFromCode(ret))
}
ret := context_enc.AvcodecReceivePacket(pkt_enc)
if ret < 0 {
if ret == -11 {
log.Println("AvcodecReceivePacket Failed des : ", ret, avutil.ErrorFromCode(ret))
avutil.AvFrameUnref(frame)
continue
}
log.Panic("AvcodecReceivePacket err ", avutil.ErrorFromCode(ret))
}
log.Println("=================================")
if ret == 0 {
data0 := pkt_enc.Data()
buf := make([]byte, pkt_enc.GetPacketSize())
start := uintptr(unsafe.Pointer(data0))
for i := 0; i < pkt_enc.GetPacketSize(); i++ {
elem := *(*uint8)(unsafe.Pointer(start + uintptr(i)))
buf[i] = elem
}
header := adts.Default()
header.SetFrameSize(uint16(len(buf)))
b := append(header.Bytes()[0:], buf[0:]...)
file.Write(b)
}
avutil.AvFrameUnref(frames[0])
}
}
avutil.AvFrameUnref(frame)
}
}
detected 8 logical cores
[Parsed_aresample_0 @ 000000000089fe00] Setting 'sample_rate' to value '44100'
[Parsed_aformat_1 @ 00000000001fd5c0] Setting 'sample_fmts' to value 'fltp'
[Parsed_aformat_1 @ 00000000001fd5c0] Setting 'channel_layouts' to value 'stereo'
[Parsed_asetnsamples_2 @ 00000000001fe6c0] Setting 'nb_out_samples' to value '1024'
[in0 @ 00000000001feac0] Setting 'sample_rate' to value '8000'
[in0 @ 00000000001feac0] Setting 'time_base' to value '1/8000'
[in0 @ 00000000001feac0] Setting 'sample_fmt' to value 's16'
[in0 @ 00000000001feac0] Setting 'channel_layout' to value 'stereo'
[in0 @ 00000000001feac0] tb:1/8000 samplefmt:s16 samplerate:8000 chlayout:stereo
[AVFilterGraph @ 0000000003ad6b80] query_formats: 5 queried, 12 merged, 0 already done, 0 delayed
[Parsed_aresample_0 @ 000000000089fe00] [SWR @ 000000000089ffc0] Using fltp internally between filters
[Parsed_aresample_0 @ 000000000089fe00] ch:2 chl:stereo fmt:s16 r:8000Hz -> ch:2 chl:stereo fmt:fltp r:44100Hz