上一节我们讲了如何基于ffmpeg-Android工程编译安卓上的支持音频的ffmpeg静态库:http://blog.csdn.net/xiejiashu/article/details/52524099,这篇文章我们将介绍如何封装安卓的解码器。

首先,为了能让我们的app调用调用,我们需要定义一套Java的native接口,解码器主要有三个接口:

  • create 创建解码器,参数分别为:

    • codec:音频编码格式,参考EasyTypes.h里面的EASY_SDK_AUDIO_CODEC_*宏定义;
    • sample_rate:采样率,通常为8000、44000等等;
    • channels:通道数,1、2分别表示单通道、双通道;
    • sample_bit:采样精度,通常为16bit; 
      返回解码器句柄,即后续接口里面用到的handle
  • decode 解码,参数为: 
    • handle :解码器句柄
    • buffer:要解码的buffer(编码后的音频数据)
    • offset:编码数据在buffer里的起始位置
    • length:编码数据的长度
    • pcm:解码后的pcm数据
    • outLen 长度至少为1的int数组,如果解码成功,那outLen[0]被置为pcm的数据长度
  • close 关闭解码器,参数为解码器的句柄。关闭后句柄无效,应该置为0.
package org.easydarwin.audio;/*** Created by John on 2016/3/18.*/
public class AudioCodec {static {System.loadLibrary("AudioCodecer");}public static native int create(int codec, int sample_rate, int channels, int sample_bit);public static native int decode(int handle, byte[] buffer, int offset, int length, byte[] pcm, int[] outLen);public static native void close(int handle);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

接下来我们要实现相应的native接口,头文件可通过调用javah命令(这里不再详述)来生成。以AAC解码来说明,create代码片段如下:

// 创建获取解码器AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_AAC);if (pCodec == NULL){LOGI("find aac decoder error");printf("find aac decoder error\r\n");return 0;}// 创建解码Context并open解码器pCodecCtx = avcodec_alloc_context3(pCodec);pCodecCtx->channels = channels;pCodecCtx->sample_rate = sample_rate;pCodecCtx->bit_rate = bit_rate;if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0){printf("open codec error\r\n");return 0;}// 分配内存,存放解码后的数据pFrame = av_frame_alloc();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

decode:

    // 源码流赋值packet.size = length;packet.data = buffer;int got_frame = 0;// 解码、数据拷贝while (pkt_pos < nLen){//  pkt_pos = 0;int got_frame = 0;src_len = avcodec_decode_audio4(pAACD->pCodecCtx, pAACD->pFrame, &got_frame, &packet);if (src_len < 0){return -3;}data_len += src_lenif (got_frame){memcpy(pAACD->pFrame, pAACD->audio_buf, len);dst_len += len;}pkt_pos += src_len;packet.data = pData + pkt_pos;packet.size = nLen - pkt_pos;}if (NULL != outLen) *outLen = dst_len;// 释放av_free_packet(&packet);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

close:

av_frame_free(&pFrame);avcodec_close(pComponent->pCodecCtx);avcodec_free_context(&pCodecCtx);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

对于其它格式的音频算法,只要在avcodec_find_decoder时传入不同的算法ID即可。

接下来,我们需要使用NDK编译出ANDROID上可以使用的动态库,为此我们需要编辑Android.mk文件,其内容如下:

# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH:= $(call my-dir)
SRC_ROOT_PATH := $(call my-dir)
LOCAL_INCLUDE := $(LOCAL_PATH)/aacdec/include
# 加载预编译的静态库
include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libavcodec.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libavdevice
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libavdevice.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libavfilter
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libavfilter.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libavformat.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libavutil.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libswresample.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := $(LOCAL_PATH)/aacdec/lib/libswscale.a
include $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_C_INCLUDES += $(LOCAL_INCLUDE)PROJECT_FILES := $(wildcard $(SRC_ROOT_PATH)/*.cpp)
PROJECT_FILES += $(wildcard $(SRC_ROOT_PATH)/*.c)
PROJECT_FILES += $(wildcard $(SRC_ROOT_PATH)/aacdec/*.cpp)$(warning $(PROJECT_FILES))
PROJECT_FILES := $(PROJECT_FILES:$(LOCAL_PATH)/%=%)
$(warning $(PROJECT_FILES))
LOCAL_SRC_FILES := $(PROJECT_FILES)LOCAL_CFLAGS := -D__unix__ -DANDROID_OS -D__arm__ -D__STDC_CONSTANT_MACROSLOCAL_MODULE    := AudioCodecerLOCAL_LDLIBS += -L$(LOCAL_PATH)/aacdec/lib -lavcodec -lswscale -lswresample -lavutil -lavformat -lavfilter -lavdevice -llog -lzCFLAGS += -mfpu=neonLOCAL_STATIC_LIBRARIES := libavcodec libswscale libswresample libavutil libavformat libavfilter libavdeviceinclude $(BUILD_SHARED_LIBRARY)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

我们这里需要把之前编译出来的静态库链接起来,生成一个动态库。其中,静态库lib文件和头文件分别放在/aacdec/lib/ 和 /aacdec/include/ 下。

接下来,cd到jni目录,执行ndk-build,如果顺利的话,我们要的动态库文件就会生成。

整个项目源码见Github

转载于:https://www.cnblogs.com/babosa/p/5904606.html

EasyDarwin开源音频解码项目EasyAudioDecoder:EasyPlayer Android音频解码库(第二部分,封装解码器接口)...相关推荐

  1. android音频编辑之音频裁剪的示例代码

    音频编辑项目的整体结构 音频裁剪方法的流程实现 获取音频文件相关信息 计算裁剪时间点对应文件中数据的位置 写入wav文件头信息 写入wav文件裁剪部分的音频数据 下面是音频裁剪效果图: 音频编辑项目的 ...

  2. android音频编辑之音频裁剪

    转载请标明出处: http://blog.csdn.net/hesong1120/article/details/79077013 本文出自:hesong的专栏 前言 本篇开始讲解音频编辑的具体操作, ...

  3. android音频资源,android音频编辑之音频裁剪的示例代码

    前言 本篇开始讲解音频编辑的具体操作,从相对简单的音频裁剪开始.要进行音频裁剪,我的方案是开启一个Service服务用于音频裁剪的耗时操作,主界面发送裁剪命令,同时注册EventBus接受裁剪的消息( ...

  4. 音频编解码(软/硬编码),音频转码

    > 音频编解码(软编码) FFMpeg视频软件编解码的.B站的ijkplayer等. 音频数据的编解码- http://blog.51cto.com/ticktick/1760191 1.And ...

  5. android音频系统之AudioTrack的使用

    今天,简单讲讲  AudioTrack的使用. 1.Android AudioTrack简介 在android中播放声音可以用MediaPlayer和AudioTrack两种方案的,但是两种方案是 ...

  6. android音频编辑之音频合成

    前言 音频编辑系列: android音频编辑之音频转换PCM与WAV android音频编辑之音频裁剪 android音频编辑之音频合成 本篇主要讲解音频PCM数据的合成,这里合成包括音频之间的拼接, ...

  7. Android音频开发(一):音频基础知识

    一.Android音频开发(一):音频基础知识 二.Android音频开发(二):录制音频(WAV及MP3格式) 三.Android音频开发(三):使用ExoPlayer播放音频 四.Android音 ...

  8. Android音频开发(四):音频播放模式

    一.Android音频开发(一):音频基础知识 二.Android音频开发(二):录制音频(WAV及MP3格式) 三.Android音频开发(三):使用ExoPlayer播放音频 四.Android音 ...

  9. Android 音频源码分析——AudioTrack设备选择

    Android 音频源码分析--AndroidRecord录音(一) Android 音频源码分析--AndroidRecord录音(二) Android 音频源码分析--AndroidRecord音 ...

最新文章

  1. 在node.js中一次读取一行文件?
  2. python随机抽取人名_用Python打造一个CRM系统(五)
  3. 偷懒大法好,用 selenium 做 web 端自动化测试
  4. linux 命令tar,Linux下tar命令详解
  5. 小米人员架构调整:组建中国区,王川任总裁
  6. html程序国庆节祝福,2018国庆节祝福祖国的话
  7. OpenCV图像、矩阵、数组介绍
  8. spark学习-55-源代码:SparkSession的的创建
  9. list怎么取数据_MongoDB 自动过滤重复数据
  10. 黑苹果mac未能安装在你的电脑上_mac电脑上全新视频剪辑软件安装包分享,让你剪辑视频从此无忧!...
  11. 安装MiniTools后,不能识别USB的问题
  12. 商业云平台和开源云平台
  13. IBM系统分析——领域建模
  14. 厦门92坐标参数讨论
  15. 快速筛选打卡时间日期等数据:EXCEL筛选查找某一时间点是否在某一时间段内
  16. 江苏高考可以用计算机嘛,2018江苏高考计算机网上评卷考生作答须知
  17. ERP软件是什么意思,买菜大妈讲的通俗易懂
  18. mes项目 组态开发项目reademe文档 待整理
  19. Neo4j技能树学习之路
  20. 微擎 人人商城 对接京东vop 对接京东商品,同步商品 地址,库存,价格,上下架等。(二)上 设置后台管理界面...

热门文章

  1. css3学习 之 css选择器(css3 属性选择器)
  2. HTML网页制作:[12]使用框架结构之frameset
  3. 安卓应用程序插件化开发框架 -AAP Framework
  4. redis源码epoll用法
  5. java源码-AQS机制
  6. javaweb:Cookie
  7. git 删除远程分支
  8. 解决QT出现XXXX.dll不能加载问题
  9. 【编译打包】twemproxy-0.4.0-2.el7.centos.src.rpm
  10. how tomcat works 1 simple web server