[ffmpeg][goav]ffmpeg代码例子pcmu重采样并转码aac格式

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值