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

曾经终败给现在 2023-06-17 05:56 229阅读 0赞

8k双声道的pcmu格式重采样44.1kHz并转码aac格式例子
src : 其中adts包是给aac填充头部的,这里就没给了。

  1. package main
  2. import(
  3. "github.com/ailumiyana/goav-incr/goav/avcodec"
  4. "github.com/ailumiyana/goav-incr/goav/avutil"
  5. "github.com/ailumiyana/goav-incr/goav/avfilter"
  6. "unsafe"
  7. "os"
  8. "io/ioutil"
  9. "log"
  10. "strconv"
  11. "adts"
  12. )
  13. func main() {
  14. avutil.AvLogSetLevel(avutil.AV_LOG_TRACE)
  15. //decoder
  16. pkt := avcodec.AvPacketAlloc()
  17. if pkt == nil {
  18. log.Panic("AvPacketAlloc failed.")
  19. }
  20. codec := avcodec.AvcodecFindDecoder(avcodec.CodecId(avcodec.AV_CODEC_ID_PCM_MULAW))
  21. if codec == nil {
  22. log.Panic("AvcodecFindDecoder failed.")
  23. }
  24. context := codec.AvcodecAllocContext3()
  25. if context == nil {
  26. log.Panic("AvcodecAllocContext3 failed.")
  27. }
  28. frame := avutil.AvFrameAlloc()
  29. if frame == nil {
  30. log.Panic("AvFrameAlloc failed.")
  31. }
  32. //设置通道数
  33. context.SetAudioDecodeParamsTest(2)
  34. context.AvcodecOpen2(codec, nil)
  35. //encoder
  36. codec_enc := avcodec.AvcodecFindEncoder(avcodec.CodecId(avcodec.AV_CODEC_ID_AAC))
  37. if codec_enc == nil {
  38. log.Panic("AvcodecFindEncoder failed.")
  39. }
  40. pkt_enc := avcodec.AvPacketAlloc()
  41. if pkt_enc == nil {
  42. log.Panic("AvPacketAlloc failed.")
  43. }
  44. context_enc := codec_enc.AvcodecAllocContext3()
  45. if context_enc == nil {
  46. log.Panic("AvcodecAllocContext3 failed.")
  47. }
  48. context_enc.SetAudioEncodeParams(128000, 44100, "stereo", avcodec.AV_SAMPLE_FMT_FLTP)
  49. err := context_enc.AvcodecOpen2(codec_enc, nil)
  50. if err < 0 {
  51. log.Panic("AvcodecOpen2 failed.")
  52. }
  53. //filter
  54. graph := avfilter.AvfilterGraphAlloc()
  55. if graph == nil {
  56. log.Fatal("AvfilterGraphAlloc Failed.")
  57. }
  58. inputs := avfilter.AvfilterInoutAlloc()
  59. outputs := avfilter.AvfilterInoutAlloc()
  60. if inputs == nil || outputs == nil {
  61. log.Fatal("AvfilterInoutAlloc Failed.")
  62. }
  63. defer avfilter.AvfilterInoutFree(inputs)
  64. defer avfilter.AvfilterInoutFree(outputs)
  65. var buffersrc *avfilter.Filter
  66. var buffersink *avfilter.Filter
  67. buffersrc = avfilter.AvfilterGetByName("abuffer")
  68. buffersink = avfilter.AvfilterGetByName("abuffersink")
  69. if buffersink == nil || buffersrc == nil {
  70. log.Panic("AvfilterGetByName Failed.")
  71. }
  72. ret := graph.AvfilterGraphParse2("aresample=44100,aformat=sample_fmts=fltp:channel_layouts=stereo,asetnsamples=1024", &inputs, &outputs)
  73. if ret < 0 {
  74. log.Panic("AvfilterInoutAlloc Failed des : ", avutil.ErrorFromCode(ret))
  75. }
  76. var ins []*avfilter.Context
  77. var outs []*avfilter.Context
  78. var frames []*avutil.Frame
  79. // inputs
  80. index := 0
  81. for cur := inputs; cur != nil; cur = cur.Next() {
  82. var in *avfilter.Context
  83. inName := "in" + strconv.Itoa(index)
  84. ret = avfilter.AvfilterGraphCreateFilter(&in, buffersrc, inName, "sample_rate=8000:time_base=1/8000:sample_fmt=s16:channel_layout=stereo", 0, graph)
  85. if ret < 0 {
  86. log.Panic("AvfilterGraphCreateFilter Failed des : ", avutil.ErrorFromCode(ret))
  87. }
  88. ins = append(ins, in)
  89. ret = avfilter.AvfilterLink(ins[index], 0, cur.FilterContext(), cur.PadIdx())
  90. if ret < 0 {
  91. log.Panic("AvfilterLink Failed des : ", avutil.ErrorFromCode(ret))
  92. }
  93. index++
  94. }
  95. // outputs
  96. index = 0
  97. for cur := outputs; cur != nil; cur = cur.Next() {
  98. var out *avfilter.Context
  99. outName := "out" + strconv.Itoa(index)
  100. ret = avfilter.AvfilterGraphCreateFilter(&out, buffersink, outName, "", 0, graph)
  101. if ret < 0 {
  102. log.Panic("AvfilterGraphCreateFilter Failed des : ", avutil.ErrorFromCode(ret))
  103. }
  104. outs = append(outs, out)
  105. ret = avfilter.AvfilterLink(cur.FilterContext(), cur.PadIdx(), outs[index], 0)
  106. if ret < 0 {
  107. log.Panic("AvfilterLink Failed des : ", avutil.ErrorFromCode(ret))
  108. }
  109. index++
  110. f := avutil.AvFrameAlloc()
  111. if f == nil {
  112. log.Panic("AvFrameAlloc failed.")
  113. }
  114. frames = append(frames, f)
  115. }
  116. ret = graph.AvfilterGraphConfig(0)
  117. if ret < 0 {
  118. log.Panic("AvfilterGraphConfig Failed des : ", avutil.ErrorFromCode(ret))
  119. }
  120. //input pcm file
  121. data, errr := ioutil.ReadFile("ilem8kmulaw.pcm")
  122. if errr != nil {
  123. log.Panic("File reading error", err)
  124. }
  125. l := len(data)
  126. //parser := make([]byte, 160)
  127. offset := -160
  128. //out aac file
  129. file, errr := os.Create("./out.aac")
  130. if errr != nil {
  131. log.Panic("Error Reading")
  132. }
  133. defer file.Close()
  134. //handle
  135. apts := int64(0)
  136. for offset + 160 < l {
  137. offset+=160
  138. pkt.AvPacketFromData(data[offset:offset+160], 160)
  139. ret := context.AvcodecSendPacket(pkt)
  140. if ret < 0 {
  141. log.Println("AvcodecSendPacket err ", avutil.ErrorFromCode(ret))
  142. }
  143. ret = context.AvcodecReceiveFrame((*avcodec.Frame)(unsafe.Pointer(frame)))
  144. if ret < 0 {
  145. log.Println("AvcodecReceiveFrame err ", avutil.ErrorFromCode(ret))
  146. }
  147. if ret == 0 {
  148. apts += 160
  149. frame.SetPts(apts)
  150. frame.SetSampleRate(8000)
  151. ret := avfilter.AvBuffersrcAddFrame(ins[0], (*avfilter.Frame)(unsafe.Pointer(frame)))
  152. if ret < 0 {
  153. log.Println("AvBuffersrcAddFrame error :", avutil.ErrorFromCode(ret))
  154. }
  155. log.Println("---------")
  156. ret = avfilter.AvBufferSinkGetFrame(outs[0], (*avfilter.Frame)(unsafe.Pointer(frames[0])))
  157. if ret == -11 {
  158. log.Println("AvBufferSinkGetFrame Failed des : ", ret, avutil.ErrorFromCode(ret))
  159. avutil.AvFrameUnref(frame)
  160. continue
  161. }
  162. if frames[0] != nil {
  163. ret = context_enc.AvcodecSendFrame((*avcodec.Frame)(unsafe.Pointer(frames[0])))
  164. if ret < 0 {
  165. log.Panic("AvcodecSendFrame err ", avutil.ErrorFromCode(ret))
  166. }
  167. ret := context_enc.AvcodecReceivePacket(pkt_enc)
  168. if ret < 0 {
  169. if ret == -11 {
  170. log.Println("AvcodecReceivePacket Failed des : ", ret, avutil.ErrorFromCode(ret))
  171. avutil.AvFrameUnref(frame)
  172. continue
  173. }
  174. log.Panic("AvcodecReceivePacket err ", avutil.ErrorFromCode(ret))
  175. }
  176. log.Println("=================================")
  177. if ret == 0 {
  178. data0 := pkt_enc.Data()
  179. buf := make([]byte, pkt_enc.GetPacketSize())
  180. start := uintptr(unsafe.Pointer(data0))
  181. for i := 0; i < pkt_enc.GetPacketSize(); i++ {
  182. elem := *(*uint8)(unsafe.Pointer(start + uintptr(i)))
  183. buf[i] = elem
  184. }
  185. header := adts.Default()
  186. header.SetFrameSize(uint16(len(buf)))
  187. b := append(header.Bytes()[0:], buf[0:]...)
  188. file.Write(b)
  189. }
  190. avutil.AvFrameUnref(frames[0])
  191. }
  192. }
  193. avutil.AvFrameUnref(frame)
  194. }
  195. }
  196. detected 8 logical cores
  197. [Parsed_aresample_0 @ 000000000089fe00] Setting 'sample_rate' to value '44100'
  198. [Parsed_aformat_1 @ 00000000001fd5c0] Setting 'sample_fmts' to value 'fltp'
  199. [Parsed_aformat_1 @ 00000000001fd5c0] Setting 'channel_layouts' to value 'stereo'
  200. [Parsed_asetnsamples_2 @ 00000000001fe6c0] Setting 'nb_out_samples' to value '1024'
  201. [in0 @ 00000000001feac0] Setting 'sample_rate' to value '8000'
  202. [in0 @ 00000000001feac0] Setting 'time_base' to value '1/8000'
  203. [in0 @ 00000000001feac0] Setting 'sample_fmt' to value 's16'
  204. [in0 @ 00000000001feac0] Setting 'channel_layout' to value 'stereo'
  205. [in0 @ 00000000001feac0] tb:1/8000 samplefmt:s16 samplerate:8000 chlayout:stereo
  206. [AVFilterGraph @ 0000000003ad6b80] query_formats: 5 queried, 12 merged, 0 already done, 0 delayed
  207. [Parsed_aresample_0 @ 000000000089fe00] [SWR @ 000000000089ffc0] Using fltp internally between filters
  208. [Parsed_aresample_0 @ 000000000089fe00] ch:2 chl:stereo fmt:s16 r:8000Hz -> ch:2 chl:stereo fmt:fltp r:44100Hz

发表评论

表情:
评论列表 (有 0 条评论,229人围观)

还没有评论,来说两句吧...

相关阅读

    相关 音频采样

    对于采样率为Fs,长度为M个采样点的音频信号x\[n\],,通过采样因子P/Q进行重采样后,这个信号的样本数可以增大或者减小。该过程可以分为如下三个步骤\[17\]: (1)

    相关 数字音频采样

    1. 什么是有限带宽插值(Bandlimited Interpolation)           在数字信号处理中,作用于离散时间信号的有限带宽插值是一个得到广泛应用

    相关 AAC音频格式分析

    AAC概述      AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术。由Fraunhof