ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

音视频编解码问题:javaCV如何快速进行音频预处理和解复用编解码(基于javaCV-FFMPEG)

2021-04-19 21:51:12  阅读:257  来源: 互联网

标签:编解码 采样率 编码 音频 复用 音视频 javaCV recorder


前言:

前面我用了很多章实现了javaCV的基本操作,包括:音视频捕捉(摄像头视频捕捉和话筒音频捕捉),推流(本地音视频或者摄像头话筒混合推流到服务器),转流(rtsp->rtmp),收流(录制)。

序:

我们知道javaCV中编码需要先取到一帧采样的音频(即采样率x通道数,我们姑且把这个称为一帧采样数据)

其实我们在该篇文章http://blog.csdn.net/eguid_1/article/details/52804246中已经对音频进行转码了。

额。。这个真没看出来(PS:博主也没看出来 0_0 !)。。。。。。。。。

我们获取了本地的音频音频数据(具体啥编码博主也不晓得,只知道是16位的, - -! ,不过这不要紧,FFMPEG能我们实现,下面将会讲到 );

其中我们做了大小端序的转换和byte[]转short[](双8位转单16位),音频编解码中这个操作我们会经常用;

然后我们使用了recoder.reacordSimples(采样率,通道数,一份采样);

对比一下音频捕获的文章:http://blog.csdn.net/eguid_1/article/details/52702385

发现了吗?没错,我们给recorder设置了一些属性:


// 不可变(固定)音频比特率  
        recorder.setAudioOption("crf", "0");  
        // 最高质量  
        recorder.setAudioQuality(0);  
        // 音频比特率  
        recorder.setAudioBitrate(192000);  
        // 音频采样率  
        recorder.setSampleRate(44100);  
        // 双通道(立体声)  
        recorder.setAudioChannels(2);  
        // 音频编/解码器  
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);

看到了吗?我们其实已经设置了编/解码格式aac,为什么呢?因为javaCV已经封装了解复用和编码这两个操作。


补充:

补充一下javaCV底层的ffmpeg解复用/编码流程:

我们在进行recoder.reacordSimples的时候javaCV底层调用ffmpeg的swr_convert()方法(详见javaCV的FFmpegFrameRecoder类974行)进行了解码操作,完成了对pcm16le编码的解复用;

解码完成之后又调用了recorder.record(Frame frame)(详见javaCV的FFmpegFrameRecoder类994行),在这个环节完成了调用了FFMPEG的avcodec_encode_audio2()方法(详见javaCV的FFmpegFrameRecoder类1006行)按照我们已经设定好的的aac格式完成了编

码操作,所以我们本身是不需要进行解复用/编码的操作的(视频也是一样,以后会讲到),因为javaCV已经帮我门做了!

到这里肯定有些小伙伴已经5脸懵bi的状态了。。。 - -!,最不幸的是,上面一堆的前言和补充知识,我们的主题还没开始。 0_0 !

eguid唯一技术博客是csdn,博主唯一交流群是群号:371249677 (点击这里进群),欢迎大家来埋汰群主

1、java音频预处理

既然javaCV已经帮我门做了解复用和编码,那么我们只需要将获得到的音频数据进行简单的预处理即可。

注:如果是文件或者服务器直播流,那么连预处理都省了,直接设置编码格式即可,不需要我们手动做任何处理。


这里讲一下特殊的byte[]流,也就是基于socket的IO流形式的音频数据处理,一般我们使用这种的情况是移动端通过socket推流到中转服务器,让中转服务器进行转码推送到流媒体服务器。

1.1、如何从byte[]流中获取一份完整的音频帧(即一帧采样数据)

就拿 8000采样率,16bit,双通道(立体声)的pcm16le编码来说吧举例说明吧

我们知道这个音频采样率是8000,位数是16bit,2个通道,那么我们就知道这个编码的一帧就是(8000x2 )个byte

1.2、音频原始数据转换

一个byte只能表示8bit数据,我们要表示16位的音频数据就需要装换为short,一个short等于2个byte,在转换的同时进行大小端序转换(大小端序问题详见http://blog.csdn.net/eguid_1/article/details/52790848),那么我们最后得到的数据应该是一个长度是8000的short数组(即short[8000])来表示一帧音频采样数据。

音频的预处理到此完毕,接下来该javaCV出场了

2、javaCV音频解复用及编码

通过上面一大堆的前言,已经知道:音频数据直接通过recorder设置音频编码参数即可自动进行解复用和编码

只需要调用recorder.recordSamples(采样率,通道数量,一份采样数据)即可。

我的天呐,这真真是用一行代码解决了C/C++好几百行的事情!











标签:编解码,采样率,编码,音频,复用,音视频,javaCV,recorder
来源: https://blog.51cto.com/u_6329998/2718442

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有