项目地址,求star
https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E6%92%AD%E6%94%BE%E9%9F%B3%E4%B9%90%EF%BC%88%E4%BF%9D%E7%A8%8B%E5%BA%8F%E4%B8%8D%E6%AD%BB%EF%BC%89

这个是FFmpeg解码出音频,给AudioTrack播放,这回才算是java与c语言之间合作

这回我们将会从c++里调用java函数,下面就是关于c++使用AudioTrack的代码

    private AudioTrack audioTrack;//    这个方法  是C进行调用  通道数public void createTrack(int sampleRateInHz,int nb_channals) {int channaleConfig;//通道数if (nb_channals == 1) {channaleConfig = AudioFormat.CHANNEL_OUT_MONO;} else if (nb_channals == 2) {channaleConfig = AudioFormat.CHANNEL_OUT_STEREO;}else {channaleConfig = AudioFormat.CHANNEL_OUT_MONO;}int buffersize=AudioTrack.getMinBufferSize(sampleRateInHz,channaleConfig, AudioFormat.ENCODING_PCM_16BIT);audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRateInHz,channaleConfig,AudioFormat.ENCODING_PCM_16BIT,buffersize,AudioTrack.MODE_STREAM);audioTrack.play();}//C传入音频数据public void playTrack(byte[] buffer, int lenth) {if (audioTrack != null && audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {audioTrack.write(buffer, 0, lenth);}}

我们再来看看c++的代码

首先注册组件,然后得到音频流

     av_register_all();AVFormatContext *pFormatCtx = avformat_alloc_context();//openif (avformat_open_input(&pFormatCtx, input, NULL, NULL) != 0) {LOGE("%s","打开输入视频文件失败");return;}//获取视频信息if(avformat_find_stream_info(pFormatCtx,NULL) < 0){LOGE("%s","获取视频信息失败");return;}int audio_stream_idx=-1;int i=0;for (int i = 0; i < pFormatCtx->nb_streams; ++i) {if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {LOGE("  找到音频id %d", pFormatCtx->streams[i]->codec->codec_type);audio_stream_idx=i;break;}}

获取解码器

    //获取解码器上下文AVCodecContext *pCodecCtx=pFormatCtx->streams[audio_stream_idx]->codec;//获取解码器AVCodec *pCodex = avcodec_find_decoder(pCodecCtx->codec_id);//打开解码器if (avcodec_open2(pCodecCtx, pCodex, NULL)<0) {}

设置缓存区,保存解码前后的数据

    //申请avpakcet,装解码前的数据AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));//申请avframe,装解码后的数据AVFrame *frame = av_frame_alloc();

设置解码出的声音一系列的属性,比如:单声道、双声道、采集点大小、采集率,还可以在这里对声音添加特效,

    //得到SwrContext ,进行重采样,具体参考http://blog.csdn.net/jammg/article/details/52688506SwrContext *swrContext = swr_alloc();//缓存区uint8_t *out_buffer = (uint8_t *) av_malloc(44100 * 2);
//输出的声道布局(立体声)uint64_t  out_ch_layout=AV_CH_LAYOUT_STEREO;
//输出采样位数  16位enum AVSampleFormat out_formart=AV_SAMPLE_FMT_S16;
//输出的采样率必须与输入相同int out_sample_rate = pCodecCtx->sample_rate;//swr_alloc_set_opts将PCM源文件的采样格式转换为自己希望的采样格式swr_alloc_set_opts(swrContext, out_ch_layout, out_formart, out_sample_rate,pCodecCtx->channel_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0,NULL);swr_init(swrContext);
//    获取通道数  2int out_channer_nb = av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO);

通过反射能够运行java函数

//    反射得到Class类型jclass david_player = env->GetObjectClass(instance);
//    反射得到createAudio方法jmethodID createAudio = env->GetMethodID(david_player, "createTrack", "(II)V");
//    反射调用createAudioenv->CallVoidMethod(instance, createAudio, 44100, out_channer_nb);jmethodID audio_write = env->GetMethodID(david_player, "playTrack", "([BI)V");

在一边解码的时候一边给数据给AudioTrack播放

    while (av_read_frame(pFormatCtx, packet) >= 0) {if (packet->stream_index == audio_stream_idx) {
//            解码  mp3   编码格式frame----pcm   frameavcodec_decode_audio4(pCodecCtx, frame, &got_frame, packet);if (got_frame) {LOGE("解码");swr_convert(swrContext, &out_buffer, 44100 * 2, (const uint8_t **) frame->data, frame->nb_samples);
//                缓冲区的大小int size = av_samples_get_buffer_size(NULL, out_channer_nb, frame->nb_samples,AV_SAMPLE_FMT_S16, 1);jbyteArray audio_sample_array = env->NewByteArray(size);env->SetByteArrayRegion(audio_sample_array, 0, size, (const jbyte *) out_buffer);env->CallVoidMethod(instance, audio_write, audio_sample_array, size);env->DeleteLocalRef(audio_sample_array);}}}

释放资源

    av_frame_free(&frame);swr_free(&swrContext);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);env->ReleaseStringUTFChars(input_, input);

FFmpeg只是音视频处理的工具,他没有播放视频和音频的能力,所以我们需要SurfaceView显示视频,AudioTrack播放声音,而且OpenGLES也能播放声音,这个后面说

下一次就是说如何将视频的声音给听换掉,也就是将音视频的解码和编码都来搞一次

转载于:https://www.cnblogs.com/jianpanwuzhe/p/8427415.html

Android 音视频深入 十一 FFmpeg和AudioTrack播放声音(附源码下载)相关推荐

  1. FFmpeg —— 裁剪视频(含音视频),不需编解码(附源码)

    说明 附上指令方式:ffmpeg -i in.mp4 -ss 00:00:10 -to 00:00:39 out.mp4   完整源码 #include <iostream>

  2. android画板需求分析,Android编程实现画板功能的方法总结【附源码下载】

    本文实例讲述了Android编程实现画板功能的方法.分享给大家供大家参考,具体如下: Android实现画板主要有2种方式,一种是用自定义View实现,另一种是通过Canvas类实现.当然自定义Vie ...

  3. android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...

    Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...

  4. Android音频实时传输与播放(四):源码下载(问题更新)【转】

    Android音频实时传输与播放(四):源码下载(问题更新) 激动人心的时刻到了有木有 ^_^ 服务端下载请点击这里,客户端下载请点击这里! 最近有朋友在下载源码使用之后,说播放出来的声音噪声很大.其 ...

  5. 短视频去水印多功能工具箱微信小程序源码下载支持多种流量主

    没错这是一款以去水印为主的一款多功能微信小程序源码 该小程序源码除了拥有去水印功能以外还拥有N款其它实用的功能 比如喝酒神器,短网址生成,历史上的今天等等如下: 短视频去水印(自带接口,速度非常快) ...

  6. android+仿iphone,Android编程实现仿iphone抖动效果的方法(附源码)

    Android编程实现仿iphone抖动效果的方法(附源码) 时间:2021-05-20 本文实例讲述了Android编程实现仿iphone抖动效果的方法.分享给大家供大家参考,具体如下: 布局文件: ...

  7. Android Camera2 实现高帧率预览录制(附源码)

    公众号回复:666,领取学习资源大礼包 来源:svvvvvvvL 地址:https://www.jianshu.com/p/0d2f200ab374 Android的相机 Camera2 在 6.0M ...

  8. Android 百度地图-实现POI的搜索(搜索周边)附源码

    首先贴出主要代码 Activity package cn.yhsh.maptest;import java.util.ArrayList; import utils.PoiOverlay; impor ...

  9. Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接

    Android 利用广播实现指定号码的短信的拦截 根据最近的学习内容,今天实现了利用广播进行指定号码的拦截 步骤: ①.写一个数据库的帮助类,实现对数据库的创建,总共创建两个数据库psms(受保护的短 ...

最新文章

  1. 自然语言处理的蓬勃发展及其未来
  2. Android 关于ListView中按钮监听的优化问题(方法二)
  3. linux系统刷分辨率,Linux下设置其分辨率及刷新率
  4. 1.通俗解释分布式系统
  5. Bootstrap 轮番插件
  6. word 的使用(四)—— 对齐与美观(表格)
  7. php中$_ENV为空解决办法
  8. Win8电脑音效怎么调?电脑音效设置方法
  9. TR转TO L_TO_CREATE_TR
  10. 湖南省张家界市谷歌高清卫星地图下载
  11. javaEE 深入理解 Session 与 Cookie
  12. 灵州会盟及民族友好历史传统研讨会在吴忠召开
  13. 怎么学编程?学编程黄金4步,太多人卡在了第二步!
  14. 【图】max51开发板(手工焊接)
  15. python ccf题解 201409-1 相邻数对
  16. java将后台数据库查询到的数据导出word文档当中
  17. 【正本清源】Synchronized 源码全解之偏向锁的获取(基于 Openjdk12)
  18. python保留字-Python保留字
  19. JAVA 安全-JWT 安全及预编译 CASE 注入等
  20. MySQL常见数据类型(小胖虎带你了解MySQL基础知识,只为博君一关注)

热门文章

  1. CertEnroll::CX509Enrollment::p_InstallResponse:ASN1 bad tag value met. 0x8009310b
  2. SAE取消每日免费云豆赠送机制
  3. 功能性农业实用技术 谋定·农业大健康-李喜贵:粤黔东西协作
  4. 功能性农业未来方向-农业大健康·徐春晖:农业品牌市场规范
  5. 自己实现spring核心功能 二
  6. PHP下实现两种ajax跨域的解决方案之jsonp
  7. 第二周 第七节 列表的使用
  8. History of program (language).
  9. unbuntu 安装MySQL
  10. 转 知道这20个正则表达式,能让你少写1,000行代码