android音视频,android音视频开发pdf下载
android音视频开发一安卓常用API
Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如AMR、MP3等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧PCM音频数据。如果想简单地做一个录音机,录制成音频文件,则推荐使用 MediaRecorder,而如果需要对音频做进一步的算法处理、或者采用第三方的编码库进行压缩、以及网络传输等应用,则建议使用 AudioRecord,其实 MediaRecorder 底层也是调用了 AudioRecord 与 Android Framework 层的 AudioFlinger 进行交互的。直播中实时采集音频自然是要用AudioRecord了。
10年积累的成都做网站、网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先做网站后付款的网站建设流程,更有大庆免费网站建设让你可以放心的选择与我们合作。
2.1 播放声音可以用MediaPlayer和AudioTrack,两者都提供了Java API供应用开发者使用。虽然都可以播放声音,但两者还是有很大的区别的。
2.2 其中最大的区别是MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。而AudioTrack只能播放已经解码的PCM流,如果对比支持的文件格式的话则是AudioTrack只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。
2.3 MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包含了AudioTrack。
2.4 在接触Android音频播放API的时候,发现SoundPool也可以用于播放音频。下面是三者的使用场景:MediaPlayer 更加适合在后台长时间播放本地音乐文件或者在线的流式资源; SoundPool 则适合播放比较短的音频片段,比如游戏声音、按键声、铃声片段等等,它可以同时播放多个音频; 而 AudioTrack 则更接近底层,提供了非常强大的控制能力,支持低延迟播放,适合流媒体和VoIP语音电话等场景。
使用 Camera API 采集视频数据并保存到文件,分别使用 SurfaceView、TextureView 来预览 Camera 数据,取到 NV21 的数据回调。
4.1 一个音视频文件是由音频和视频组成的,我们可以通过MediaExtractor、MediaMuxer把音频或视频给单独抽取出来,抽取出来的音频和视频能单独播放;
4.2 MediaMuxer的作用是生成音频或视频文件;还可以把音频与视频混合成一个音视频文件。
文献资料
Android -- 音视频基础知识
帧,是视频的一个基本概念,表示一张画面,如上面的翻页动画书中的一页,就是一帧。一个视频就是由许许多多帧组成的。
帧率,即单位时间内帧的数量,单位为:帧/秒 或fps(frames per second)。一秒内包含多少张图片,图片越多,画面越顺滑,过渡越自然。 帧率的一般以下几个典型值:
24/25 fps:1秒 24/25 帧,一般的电影帧率。
30/60 fps:1秒 30/60 帧,游戏的帧率,30帧可以接受,60帧会感觉更加流畅逼真。
85 fps以上人眼基本无法察觉出来了,所以更高的帧率在视频里没有太大意义。
这里我们只讲常用到的两种色彩空间。
RGB的颜色模式应该是我们最熟悉的一种,在现在的电子设备中应用广泛。通过R G B三种基础色,可以混合出所有的颜色。
这里着重讲一下YUV,这种色彩空间并不是我们熟悉的。这是一种亮度与色度分离的色彩格式。
早期的电视都是黑白的,即只有亮度值,即Y。有了彩色电视以后,加入了UV两种色度,形成现在的YUV,也叫YCbCr。
Y:亮度,就是灰度值。除了表示亮度信号外,还含有较多的绿色通道量。
U:蓝色通道与亮度的差值。
V:红色通道与亮度的差值。
音频数据的承载方式最常用的是 脉冲编码调制 ,即 PCM 。
在自然界中,声音是连续不断的,是一种模拟信号,那怎样才能把声音保存下来呢?那就是把声音数字化,即转换为数字信号。
我们知道声音是一种波,有自己的振幅和频率,那么要保存声音,就要保存声音在各个时间点上的振幅。
而数字信号并不能连续保存所有时间点的振幅,事实上,并不需要保存连续的信号,就可以还原到人耳可接受的声音。
根据奈奎斯特采样定理:为了不失真地恢复模拟信号,采样频率应该不小于模拟信号频谱中最高频率的2倍。
根据以上分析,PCM的采集步骤分为以下步骤:
采样率,即采样的频率。
上面提到,采样率要大于原声波频率的2倍,人耳能听到的最高频率为20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz,更高的通常为48kHz。
采样位数,涉及到上面提到的振幅量化。波形振幅在模拟信号上也是连续的样本值,而在数字信号中,信号一般是不连续的,所以模拟信号量化以后,只能取一个近似的整数值,为了记录这些振幅值,采样器会采用一个固定的位数来记录这些振幅值,通常有8位、16位、32位。
位数越多,记录的值越准确,还原度越高。
最后就是编码了。由于数字信号是由0,1组成的,因此,需要将幅度值转换为一系列0和1进行存储,也就是编码,最后得到的数据就是数字信号:一串0和1组成的数据。
整个过程如下:
声道数,是指支持能不同发声(注意是不同声音)的音响的个数。 单声道:1个声道
双声道:2个声道
立体声道:默认为2个声道
立体声道(4声道):4个声道
码率,是指一个数据流中每秒钟能通过的信息量,单位bps(bit per second)
码率 = 采样率 * 采样位数 * 声道数
这里的编码和上面音频中提到的编码不是同个概念,而是指压缩编码。
我们知道,在计算机的世界中,一切都是0和1组成的,音频和视频数据也不例外。由于音视频的数据量庞大,如果按照裸流数据存储的话,那将需要耗费非常大的存储空间,也不利于传送。而音视频中,其实包含了大量0和1的重复数据,因此可以通过一定的算法来压缩这些0和1的数据。
特别在视频中,由于画面是逐渐过渡的,因此整个视频中,包含了大量画面/像素的重复,这正好提供了非常大的压缩空间。
因此,编码可以大大减小音视频数据的大小,让音视频更容易存储和传送。
视频编码格式有很多,比如H26x系列和MPEG系列的编码,这些编码格式都是为了适应时代发展而出现的。
其中,H26x(1/2/3/4/5)系列由ITU(International Telecommunication Union)国际电传视讯联盟主导
MPEG(1/2/3/4)系列由MPEG(Moving Picture Experts Group, ISO旗下的组织)主导。
当然,他们也有联合制定的编码标准,那就是现在主流的编码格式H264,当然还有下一代更先进的压缩编码标准H265。
H264是目前最主流的视频编码标准,所以我们后续的文章中主要以该编码格式为基准。
H264由ITU和MPEG共同定制,属于MPEG-4第十部分内容。
我们已经知道,视频是由一帧一帧画面构成的,但是在视频的数据中,并不是真正按照一帧一帧原始数据保存下来的(如果这样,压缩编码就没有意义了)。
H264会根据一段时间内,画面的变化情况,选取一帧画面作为完整编码,下一帧只记录与上一帧完整数据的差别,是一个动态压缩的过程。
在H264中,三种类型的帧数据分别为
I帧:帧内编码帧。就是一个完整帧。
P帧:前向预测编码帧。是一个非完整帧,通过参考前面的I帧或P帧生成。
B帧:双向预测内插编码帧。参考前后图像帧编码生成。B帧依赖其前最近的一个I帧或P帧及其后最近的一个P帧。
全称:Group of picture。指一组变化不大的视频帧。
GOP的第一帧成为关键帧:IDR
IDR都是I帧,可以防止一帧解码出错,导致后面所有帧解码出错的问题。当解码器在解码到IDR的时候,会将之前的参考帧清空,重新开始一个新的序列,这样,即便前面一帧解码出现重大错误,也不会蔓延到后面的数据中。
DTS全称:Decoding Time Stamp。标示读入内存中数据流在什么时候开始送入解码器中进行解码。也就是解码顺序的时间戳。
PTS全称:Presentation Time Stamp。用于标示解码后的视频帧什么时候被显示出来。
前面我们介绍了RGB和YUV两种图像色彩空间。H264采用的是YUV。
YUV存储方式分为两大类:planar 和 packed。
planar如下:
packed如下:
上面说过,由于人眼对色度敏感度低,所以可以通过省略一些色度信息,即亮度共用一些色度信息,进而节省存储空间。因此,planar又区分了以下几种格式:YUV444、 YUV422、YUV420。
YUV 4:4:4采样,每一个Y对应一组UV分量。
YUV 4:2:2采样,每两个Y共用一组UV分量。
YUV 4:2:0采样,每四个Y共用一组UV分量。
其中,最常用的就是YUV420。
YUV420属于planar存储方式,但是又分两种类型:
YUV420P:三平面存储。数据组成为YYYYYYYYUUVV(如I420)或YYYYYYYYVVUU(如YV12)。
YUV420SP:两平面存储。分为两种类型YYYYYYYYUVUV(如NV12)或YYYYYYYYVUVU(如NV21)
原始的PCM音频数据也是非常大的数据量,因此也需要对其进行压缩编码。
和视频编码一样,音频也有许多的编码格式,如:WAV、MP3、WMA、APE、FLAC等等,音乐发烧友应该对这些格式非常熟悉,特别是后两种无损压缩格式。
但是,我们今天的主角不是他们,而是另外一个叫AAC的压缩格式。
AAC是新一代的音频有损压缩技术,一种高压缩比的音频压缩算法。在MP4视频中的音频数据,大多数时候都是采用AAC压缩格式。
AAC格式主要分为两种:ADIF、ADTS。
ADIF:Audio Data Interchange Format。音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。这种格式常用在磁盘文件中。
ADTS:Audio Data Transport Stream。音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
ADIF数据格式:
ADTS 一帧 数据格式(中间部分,左右省略号为前后数据帧):
AAC内部结构也不再赘述,可以参考AAC 文件解析及解码流程
细心的读者可能已经发现,前面我们介绍的各种音视频的编码格式,没有一种是我们平时使用到的视频格式,比如:mp4、rmvb、avi、mkv、mov...
没错,这些我们熟悉的视频格式,其实是包裹了音视频编码数据的容器,用来把以特定编码标准编码的视频流和音频流混在一起,成为一个文件。
例如:mp4支持H264、H265等视频编码和AAC、MP3等音频编码。
我们在一些播放器中会看到,有硬解码和软解码两种播放形式给我们选择,但是我们大部分时候并不能感觉出他们的区别,对于普通用户来说,只要能播放就行了。
那么他们内部究竟有什么区别呢?
在手机或者PC上,都会有CPU、GPU或者解码器等硬件。通常,我们的计算都是在CPU上进行的,也就是我们软件的执行芯片,而GPU主要负责画面的显示(是一种硬件加速)。
所谓软解码,就是指利用CPU的计算能力来解码,通常如果CPU的能力不是很强的时候,一则解码速度会比较慢,二则手机可能出现发热现象。但是,由于使用统一的算法,兼容性会很好。
硬解码,指的是利用手机上专门的解码芯片来加速解码。通常硬解码的解码速度会快很多,但是由于硬解码由各个厂家实现,质量参差不齐,非常容易出现兼容性问题。
MediaCodec 是Android 4.1(api 16)版本引入的编解码接口,是所有想在Android上开发音视频的开发人员绕不开的坑。
由于Android碎片化严重,虽然经过多年的发展,Android硬解已经有了很大改观,但实际上各个厂家实现不同, 还是会有一些意想不到的坑。
相对于FFmpeg,Android原生硬解码还是相对容易入门一些,所以接下来,我将会从MediaCodec入手,讲解如何实现视频的编解码,以及引入OpenGL实现对视频的编辑,最后才引入FFmpeg来实现软解,算是一个比较常规的音视频开发入门流程吧。
Android音视频【十二】使用OpenSLES和AudioTrack进行播放PCM
本节我们学习下如何播放pcm数据,在Android中有两种方法:一种是使用java层的 AudioTrack 方法,一种是使用底层的 OpenSLES 直接在 jni 层调用系统的 OpenSLES的c方法 实现。
两种使用场景不一样:
AudioTrack 一般用于 比如本地播放一个pcm文件/流,又或者播放解码后的音频的pcm流,API较简单。
OpenSLES 一般用于一些播放器中开发中,比如音频/视频播放器,声音/音频的播放采用的OpenSLES,一是播放器一般是c/c++实现,便于直接在c层调用OpenSLES的API,二也是如果用AudioTrack进行播放,务必会带来java和jni层的反射调用的开销,API较复杂。
可以根据业务自行决定来进行选择。
AudioTrack的方式使用较简单,直接在java层。
指定采样率,采样位数,声道数进行创建。
其中44100是采样率, AudioFormat.CHANNEL_OUT_STEREO 为双声道,还有 CHANNEL_OUT_MONO 单声道。 AudioFormat.ENCODING_PCM_16BIT 为采样位数16位,还有 ENCODING_PCM_8BIT 8位。 minBufferSize 是播放器缓冲的大小,也是根据采样率和采样位数,声道数 进行获取,只有满足最小的buffer才去操作底层进程播放。
最后一个参数mode。可以指定的值有 AudioTrack.MODE_STREAM 和 AudioTrack.MODE_STATIC 。
MODE_STREAM 适用于大多数的场景,比如动态的处理audio buffer,或者播放很长的音频文件,它是将audio buffers从java层传递到native层。音频播放时音频数据从Java流式传输到native层的创建模式。
MODE_STATIC 适用场景,比如播放很短的音频,它是一次性将全部的音频资源从java传递到native层。音频数据在音频开始播放前仅从Java传输到native层的创建模式。
是的,就这么一个方法。注意此方法是同步方法,是个耗时方法,一般是开启一个线程循环调用 write 方法进行写入。
注意在调用 write 方法前需要调用 audioTrack.play() 方法开始播放。
因为是pcm裸数据,无法像mediaplayer一样提供了API。所以需要自己处理下。可以利用 getPlaybackHeadPosition 方法。
getPlaybackHeadPosition() 的意思是返回以帧为单位表示的播放头位置
getPlaybackRate() 的意思是返回以Hz为单位返回当前播放采样率。
所以当前播放时间可以通过如下方式获取
OpenSLES:(Open Sound Library for Embedded Systems).
OpenSLES是跨平台是针对嵌入式系统精心优化的硬件音频加速API。使用OpenSLES进行音频播放的好处是可以不依赖第三方。比如一些音频或者视频播放器中都是用OpenSLES进行播放解码后的pcm的,这样免去了和java层的交互。
在Android中使用OpenSLES首先需要把Android 系统提供的so链接到外面自己的so。在CMakeLists.txt脚本中添加链接库OpenSLES。库的名字可以在 类似如下目录中
需要去掉lib
然后导入头文件即可使用了OpenSLES提供的底层方法了。
创建使用的步骤大致分为:
一个 SLObjectItf 里面可能包含了多个Interface,获取Interface通过 GetInterface 方法,而 GetInterface 方法的地2个参数 SLInterfaceID 参数来指定到的需要获取Object里面的那个Interface。比如通过指定 SL_IID_ENGINE 的类型来获取 SLEngineItf 。我们可以通过 SLEngineItf 去创建各种Object,例如播放器、录音器、混音器的Object,然后在用这些Object去获取各种Interface去实现各种功能。
如上所说,SLEngineItf可以创建混音器的Object。
在创建播放器前需要创建音频的配置信息(比如采样率,声道数,每个采样的位数等)
开始播放后会不断的回调这个 pcmBufferCallBack 函数将音频数据压入队列
(*pcmBufferQueue)-RegisterCallback(pcmBufferQueue, pcmBufferCallBack, this);
如果想要暂停播放参数直接设置为SL_PLAYSTATE_PAUSED,若暂停后继续播放设置参数为SL_PLAYSTATE_PLAYING即可。若想要停止播放参数设置为SL_PLAYSTATE_STOPPED即可。
首先获取播放器的用于控制音量的接口SLVolumeItf pcmVolumePlay
然后动态设置
首先也是获取播放器的用于控制音量的接口SLMuteSoloItf pcmMutePlay
然后动态设置
看起来控制还是蛮简单的哈。先熟悉这么多,OpenSLES还是蛮强大的。
Android 音视频01 --- H264的基本原理01
H264压缩技术主要采用了以下几种方法对视频数据进行压缩。包括:
解决的是空域数据冗余问题。
解决的是时域数据冗徐问题
将空间上的相关性变为频域上无关的数据然后进行量化。
经过压缩后的帧分为:I帧,P帧和B帧:
关键帧,采用帧内压缩技术。
向前参考帧,在压缩时,只参考前面已经处理的帧。采用帧音压缩技术。
双向参考帧,在压缩时,它即参考前而的帧,又参考它后面的帧。采用帧间压缩技术。
除了I/P/B帧外,还有图像序列GOP。
H264的基本原理其实非常简单,下我们就简单的描述一下H264压缩数据的过程。通过摄像头采集到的视频帧(按每秒 30 帧算),被送到 H264 编码器的缓冲区中。编码器先要为每一幅图片划分宏块。
划分好宏块后,计算宏块的象素值。以此类推,计算一幅图像中每个宏块的像素值。
对于视频数据主要有两类数据冗余,一类是时间上的数据冗余,另一类是空间上的数据冗余。其中时间上的数据冗余是最大的。为什么说时间上的冗余是最大的呢?假设摄像头每秒抓取30帧,这30帧的数据大部分情况下都是相关联的。也有可能不止30帧的的数据,可能几十帧,上百帧的数据都是关联特别密切的。
H264编码器会按顺序,每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度。如下图:
在H264编码器中将帧分组后,就要计算帧组内物体的运动矢量了。
H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了。
运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。
我们把运动矢量与补偿称为 帧间压缩技术 ,它解决的是视频帧在时间上的数据冗余。除了帧间压缩,帧内也要进行数据压缩,帧内数据压缩解决的是空间上的数据冗余。
人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感。所以基于一些研究,可以将一幅图像中人眼不敏感的数据去除掉。这样就提出了帧内预测技术。
一幅图像被划分好宏块后,对每个宏块可以进行 9 种模式的预测。找出与原图最接近的一种预测模式。然后,将原始图像与帧内预测后的图像相减得残差值。再将我们之前得到的预测模式信息一起保存起来,这样我们就可以在解码时恢复原图了,经过帧内与帧间的压缩后,虽然数据有大幅减少,但还有优化的空间。
可以将残差数据做整数离散余弦变换,去掉数据的相关性,进一步压缩数据。
上面的帧内压缩是属于有损压缩技术。也就是说图像被压缩后,无法完全复原。而CABAC属于无损压缩技术。
无损压缩技术大家最熟悉的可能就是哈夫曼编码了,给高频的词一个短码,给低频词一个长码从而达到数据压缩的目的。MPEG-2中使用的VLC就是这种算法,我们以 A-Z 作为例子,A属于高频数据,Z属于低频数据。看看它是如何做的。
CABAC也是给高频数据短码,给低频数据长码。同时还会根据上下文相关性进行压缩,这种方式又比VLC高效很多。
制定了相互传输的格式,将宏快 有组织,有结构,有顺序的形成一系列的码流。这种码流既可 通过 InputStream 网络流的数据进行传输,也可以封装成一个文件进行保存,主要作用是为了传输。
组成H264码流的结构中 包含以下几部分 ,从大到小排序依次是:
H264视频序列,图像,片组,片,NALU,宏块 ,像素。
NAL层:(Network Abstraction Layer,视频数据网络抽象层) : 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。
VCL层:(Video Coding Layer,视频数据编码层) : 对视频原始数据进行压缩
起始码0x 00 00 00 01 或者 0x 00 00 01 作为 分隔符 。
两个 0x 00 00 00 01之间的字节数据 是表示一个NAL Unit。
I 帧的特点:
1.分组:把几帧图像分为一组(GOP,也就是一个序列),为防止运动变化,帧数不宜取多。
2.定义帧:将每组内各帧图像定义为三种类型,即I帧、B帧和P帧;
3.预测帧:以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;
4.数据传输:最后将I帧数据与预测的差值信息进行存储和传输。
1.更高的编码效率:同H.263等标准的特率效率相比,能够平均节省大于50%的码率。
2.高质量的视频画面:H.264能够在低码率情况下提供高质量的视频图像,在较低带宽上提供高质量的图像传输是H.264的应用亮点。
3.提高网络适应能力:H.264可以工作在实时通信应用(如视频会议)低延时模式下,也可以工作在没有延时的视频存储或视频流服务器中。
4.采用混合编码结构:同H.263相同,H.264也使用采用DCT变换编码加DPCM的差分编码的混合编码结构,还增加了如多模式运动估计、帧内预测、多帧预测、基于内容的变长编码、4x4二维整数变换等新的编码方式,提高了编码效率。
5.H.264的编码选项较少:在H.263中编码时往往需要设置相当多选项,增加了编码的难度,而H.264做到了力求简洁的“回归基本”,降低了编码时复杂度。
6.H.264可以应用在不同场合:H.264可以根据不同的环境使用不同的传输和播放速率,并且提供了丰富的错误处理工具,可以很好的控制或消除丢包和误码。
7.错误恢复功能:H.264提供了解决网络传输包丢失的问题的工具,适用于在高误码率传输的无线网络中传输视频数据。
8.较高的复杂度:264性能的改进是以增加复杂性为代价而获得的。据估计,H.264编码的计算复杂度大约相当于H.263的3倍,解码复杂度大约相当于H.263的2倍。
H.264的目标应用涵盖了目前大部分的视频服务,如有线电视远程监控、交互媒体、数字电视、视频会议、视频点播、流媒体服务等。H.264为解决不同应用中的网络传输的差异。定义了两层:视频编码层(VCL:Video Coding Layer)负责高效的视频内容表示,网络提取层(NAL:Network Abstraction Layer)负责以网络所要求的恰当的方式对数据进行打包和传送。
Android音视频系列(七):PCM音频单声道与双声道的相互转换
上一篇我们已经学习了PCM音频的保存格式,这一篇我们通过掌握的知识,完成PCM音频的单声道和双声道的互相转换。
首先我们把上一篇的最核心部分贴出来:
我们首先完成单声道转双声道的操作。
单声道转双声道的基本原理:
首先我录制了一个音频保存到ArrayList中:
录制的是16位的数据,所以我们每一个采样的数据会占据两位,所以在拷贝的过程中,我们也要每两位拷贝一次:
单声道转声道的操作就完成了。
双声道转单声道的原理:
我们可以按照单声道双声道的做法,每四位取前两位或后两位的数据即可。但是这里我们换一种做法。
这里我们使用了ByteBuffer帮助我们把Byte转成Short。其中有一个很重要的坑,就是设置Byte转Short的规则:
所以我们一定要确保高低位的顺序,否则得到的Short一定是错的,经过测试,录制的音频是低位在前,所以我们修改ByteBuffer默认的高位在前的配置:
相同的原理,我们需要Byte转Int都可以借助对应的Buffer进行读取,非常的方便。
基本流程和第一种方法一样,如果是你用的Java,你还可以通过位运算进行Short和Byte的转换,但是kotlin的对应的运算符却无法正确转换,具体原因还不清楚,这也是为什么我使用了Buffer进行转换的原因。
只要我们掌握了PCM的保存格式,单声道和双声道的互相转换还是非常轻松的,下一篇我们来了解一下新的音频格式:WAV。
Android音视频开发——H264的基本概念
ffmpeg常用命令
封装格式 。
编码的本质就是压缩数据
音频编码的作用: 将音频采样数据( PCM 等)压缩成音频码流,从而降低音频的数据量。 常用的音频编码方式有以下几种:
H264压缩技术主要采用了以下几种方法对视频数据进行压缩。包括:
经过压缩后的帧分为:I帧,P帧和B帧:
除了I/P/B帧外,还有图像序列GOP。
组成码流的结构中,包含了以下几个部分,从大到小依次是:
H264视频序列,图像,片组,片,NALU,宏块,像素
H264功能分为两层:
1.H264视频序列包括一系列的NAL单元,每个NAL单元包含一个RBSP。
2.一个原始的H.264由 N个NALU单元组成
3.NALU单元由[StartCode][NALU Header][NALU Payload]三部分组成
5.NAL Header
由三部分组成forbidden_bit(1bit)(禁止位),nal_reference_bit(2bits)(优先级,,值越大,该NAL越重要),nal_unit_type(5bits)(类型)
nal_unit_type
6.NAL的解码单元的流程如下
分享题目:android音视频,android音视频开发pdf下载
分享路径:http://azwzsj.com/article/dsdhdic.html