首页
学习
活动
专区
工具
TVP
发布

阿利民

专栏作者
22
文章
29037
阅读量
15
订阅数
后话:安卓音频延迟带来的应用
有许多对音频延迟要求严格的应用程序,比如游戏、MIDI、DAW(数字音频工作站)、交互式音频应用程序,以及当前火热的虚拟现实应用。这类应用在Apple平台上蓬勃发展,并且为IOS开发者带来了巨额收益,但是这在Android平台上基本不存在。
阿利民
2022-05-16
7990
如何保证Android音频低延迟
为了更好的理解Android音频延迟产生的原因,最好将总的环路延迟分为以下两个部分:
阿利民
2022-05-16
1.9K0
Android 6.0以后的音频延迟改进
随着 Android 6.0 Marshmallow 的部署,华为 Nexus 6P 的往返音频延迟大大改善了 18 毫秒,HTC Nexus 9 的时钟延迟为 15 毫秒。在上一篇文章中提到,10毫秒以内的环路延迟才能被称为专业音频。
阿利民
2022-05-16
5060
什么是Android 10毫秒问题?
对超过4,238种不同Android手机型号/版本进行了音频延迟测试,数据表明Android在音频延迟问题上得到了很大改进,但随着当前媒体技术的发展,Android的这些优化还远远不够。迄今为止,Android N在音频延迟方面有任何改进,音频的延迟问题仍然制约着Android音频应用的发展。
阿利民
2022-05-16
9720
高仿剪映视频多轨剪辑页实现
剪映是当下比较火的一款手机视频剪辑工具,由抖音官方推出,可用于手机短视频的剪辑制作,拥有强大的多轨编辑能力。其中视频剪辑页用于剪辑的View拥有出色的交互性,很考验Android的基础能力,值得拿出来学习一下。   观察剪映的视频剪辑页面,可见主要有时间轴、视频轨道、时间游标和预览窗口四部分组成。时间轴用于展示当前的时间长度和时间刻度,通过缩放手势可以改变最小刻度值,拖动可以对音视频进行seek。视频轨道用于显示轨道在时间轴上的长度、以及轨道信息,同时视频轨道会显示对应时间的帧图像,而音频轨道则会显示波形图。时间游标会固定在整个View的中间位置,虽然叫它游标,但实际上并不会移动,只能通过移动时间轴和视频轨道来表示当前的时间位置。预览窗口用于显示视频帧,通常是SurfaceView或TextureView,比较简单,非本文的重点。
阿利民
2022-05-16
1.3K0
「Skia学习笔记」一、使用CMake交叉编译Skia
  Skia是一个高性能的跨平台2D图形库,由Google开源并维护。Skia能够对字体、坐标转换、点阵图、矢量图以及矢量动画等进行高效的处理,代码结构和接口异常简洁,并且支持OpenGL、Vulkan、甚至OpenCL等硬件加速特性,是一个理想的2D图形库。
阿利民
2022-05-16
3.7K1
五分钟学会如何利用矩阵进行平面坐标系转换
在图形图像领域,矩阵是一个应用广泛,且极其重要的工具。简单的,我们在OpenGL的Shader中,可以利用矩阵进行视图变换,比如透视、投影等。但本文不打算讨论这些内容,而是聚焦在如何利用矩阵把坐标从一个坐标系变换到另一个坐标系,并且保证坐标的相对位置不变,即计算一个坐标系上的点在另一个坐标系的投影。本文只探讨平面坐标系的问题,并且假设读者对矩阵知识有一定的了解,如果对矩阵比较陌生,建议先复习一下这部分知识。
阿利民
2022-05-16
2.2K0
五分钟用C++11实现Android系统的Handler机制
线程作为系统的基础资源,相信大多数读者都有使用到。一般情况下我们会直接开一个线程做一些耗时操作,处理完之后让线程自动结束,资源被系统回收。这种简单粗暴的方法不少读者、甚至一些大厂的APP都在用。以Java语言为例,我们可以直接new一个Thread对象,然后覆盖run方法,最后调一下start方法便可以成功运行一个线程。如果我们每次异步做一些耗时处理都单独开启一个线程,比如异步加载网络图片这种高并发操作,每张图片都开一个线程的话,必然会造成线程资源的浪费,而且也没有很好的方法去处理跨线程通讯的问题。由于语言层面的低成本导致系统的线程资源被滥用,已经成为了一个很普遍的现象。   Android系统的Handler是一种很好的解决以上问题的机制,如果能够在C/C++实现这样一套机制,将会极大的降低C/C++多线程的使用成本。通过本文你将了解到Android系统的Handler的实现原理,以及如何使用C/C++来实现这样一套机制。本文不打算过多的介绍Android系统中的源码实现,而是直接使用C++11来实现。
阿利民
2022-05-16
4640
一种基于广播的模块化架构简单实现
相信不少读者在开发时都有这样的困扰,项目刚开始时,代码量少,效率还可以,可维护性也不错。但随着项目的迭代,添加了各种各样的需求后,代码日积月累臃肿不堪,软件效率开始变得低下,可维护性变差,最后甚至被新人各种吐槽,这时候软件架构就显得尤为重要了。架构是软件开发的基础,直接影响着软件运行效率、代码的可维护性、可扩展性以及可读性。开始新项目时,先设计一个好的架构往往会让往后的开发事半功倍。   软件架构指的是系统的一些列抽象,用于指导软件系统的开发,并且与具体的业务无关。软件架构通常也描述了系统各个元件之间的逻辑关系,这个逻辑关系也可以简单理解为模块化。本文将向读者推荐一种基于广播的模块化架构,以下简称架构。   本文不打算向读者介绍庞大成熟的架构设计,而是为读者提供一种快速简单有效的解决方案。如果你从来没有考虑过系统架构,希望通过本文能够让你重新思考这一基础问题。如果你对架构设计有一定的经验,也许也能够给你不一样的视角。
阿利民
2022-05-16
2660
memcpy速度太慢?掌握这个技术让内存拷贝效率成倍提升
memcpy是C/C++的一个标准函数,原型void *memcpy(void *dest, const void *src, size_t n),用于从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。 neon是适用于ARM Cortex-A系列处理器的一种128位SIMD(Single Instruction, Multiple Data,单指令、多数据)扩展结构。neon支持一次指令处理多个数据,比如处理8个8-bit、4个16-bit、2个32-bit或1个64-bit。正是这个特性可以用于加速内存拷贝。   在正常情况下memcpy的性能已经足够使用了,但是当我们因为某些原因在拷贝大内存遇到瓶颈的时候,可以考虑使用neon来加速内存拷贝。比如我在使用glMapBufferRange把PBO从GPU内存映射到CPU内存的时候遇到了耗时问题,拷贝921600字节的数据需要30ms,在使用neon后,内存拷贝耗时直接降低到了4ms,相差将近8倍。事实上,在arm平台上使用neon指令可以高效提升数据并行处理性能,而不仅仅局限于内存拷贝。google开源的libyuv内部也使用了neon指令来并行处理数据。
阿利民
2022-05-16
4.7K0
史上全最的WAV格式详解
  WAV即WAVE,是经典的Windows音频数据封装格式,由Microsoft开发。数据本身格式为PCM,也可以支持一些编码格式的数据,比如最近流行的AAC编码。如果是PCM,则为无损格式,文件会比较大,并且大小相对固定,可以使用以下公式计算文件大小。
阿利民
2022-05-16
3.5K0
你真的会用JNI吗?这些小技巧99%的人都不知道
  使用Java环境和语言能够开发安全的应用程序,但是某些程序需要在Java环境之外执行任务,比如:
阿利民
2022-05-16
9660
PBO是OpenGL最高效的像素拷贝方式吗?
  OpenGL ES作为移动设备的主要图形API,是客户端调用GPU的主要入口,不管是做游戏还是音视频,都给我们提供了强大的支持。   而在音视频领域,相信不少同学都有从FBO读取像素数据的需求,熟悉OpenGL ES的童鞋应该首先想到了glReadPixels,而了解更为深入的童鞋相信都会使用更为高效的PBO。   在Android平台上,PBO是从FBO读取像素数据最高效的的方法吗。显然不是,否则这篇文章就没有意义了。下面我们来盘点Android下有哪些从FBO读取像素数据的方式,以及最高效的方式。
阿利民
2022-05-16
1.8K0
「Android音视频编码那点破事」第八章,X264实现H264编码以及MediaMuxer的另类用法
  x264是目前使用最广泛、效率最高的h264编码库,著名的音视频处理库ffmpeg也支持x264的扩展。如果你的项目用于商业用途,建议选用免费的openh264。   相比x264,可能著名的ffmpeg更广为人知。但是我们为什么不使用ffmpeg呢。正如本系列文章的序章所说,如果你只是打算用于h264编码,完全没必要使用庞大复杂ffmpeg,反而选择短小精悍的x264更适合你。不仅可以使用更小的so库(这在移动平台很有必要),而且也不需要再去啃ffmpeg枯燥复杂的代码。我是前前后后看了五遍才勉强看懂,一直处于看了又忘,忘了又看的状态,似会非会的叠加状态。相比之下x264的流程更为短小清晰,使用更为简单。
阿利民
2022-05-16
7670
「Android音视频编码那点破事」第七章,在Linux下编译Android版X264
  关于x264的编译比较简单,网上的教程也挺多的,这里只是总结一下,多个资源,方便新人学习。系统建议使用linux,本教程使用的是ubuntu。
阿利民
2022-05-16
3560
「Android音视频编码那点破事」第六章,使用MediaMuxer对音视频进行混合封装
  MediaMuxer的使用比较简单,方法很少,就那么几个。但是需要注意的是我们添加音视频轨的时候,MediaMuxer.addTrack(MediaFormat)需要一个MediaFormat参数,而这个参数不是我们打开MediaCodec的时候简单构造的那个,这个MediaFormat必须是从MediaCodec.getOutputFormat()获取的,他们完全不一样。如果我们直接使用自己简单构造的MediaFormat,是无法写入音视频数据的。   说必须有点绝对了,这只是官方推荐用法而已。其实如果有必要,我们完全可以自己构造用于添加音视频轨道的MediaFormat,这个我会在第八章教大家怎么做。   我们先看一下MediaMuxer的主要方法:
阿利民
2022-05-16
7260
「Android音视频编码那点破事」第五章,使用MediaCodec编码AAC音频数据
  在上一章我们讲到了MediaCodec的工作流程,以及如何利用MediaCodec进行H264编码。这一章的内容同样是MediaCodec,只不过是编码音频为AAC,整个流程大同小异。   上一章我们利用MediaCodec编码视频时,使用了Surface,所以可以不直接操作输入缓冲区队列。但是编码音频的时候,由于无法使用Surface,所以需要直接操作输入缓冲区队列。   这里我们需要通过AudioRecord采集PCM数据,然后把采集到的数据送进编码器进行编码。所以首先我们要初始化一个AudioRecord对象。   要使用录音,需要申请录音权限。
阿利民
2022-05-16
4080
「Android音视频编码那点破事」第四章,使用MediaCodec实现H264编码
  说到Android的视频硬编码,很多新人首先会想到MediaRecorder,这可以说是Android早期版本视频硬编码的唯一选择。这个类的使用很简单,只需要给定一个Surface(输入)和一个File(输出),它就给你生成一个标准的mp4文件。   但越是简单的东西便意味着越难以控制,MediaRecorder的缺点很明显。相信很多人在接触到断点视频录制这个需求的时候,首先会想到使用MediaRecorder,很遗憾,这个东西并不能给你很多期待,就像一开始的我一样。   首先,MediaRecorder并没有断点录制的API,当然你可以使用一些“小技巧”,每次录制的时候,都把MediaRecorder stop掉,然后再次初始化,这样就会生成一系列的视频,最后把它们拼接起来。然而问题在于,每次初始化MediaRecorder都需要消耗很长时间,这意味着,当用户快速点击录制按钮的时候可能会出现问题。对于这个问题,你可以等到MediaRecorder初始化完成才让用户点击开始录制,但是这样往往会因为等待时间过长,导致用户体验极差。   这种情况下,一个可控的视频编码器是必须的。虽然在Android 4.4以前我们没得选择,但是在Android 4.4之后,我们有了MediaCodec,一个完全可控的视频编码器,虽然无法直接输出mp4(需要配合MediaMuxer来对音视频进行混合,最终输出mp4,或者其它封装格式)。如今的Android生态,大部分手机都已经是Android 5.0系统,完全可以使用MediaCodec来进行音视频编码的开发,而MediaRecorder则降级作为一个提高兼容性的备选方案。   废话不多说,我们直接步入正题。要想正确的使用MediaCodec,我们首先得先了解它的工作流程,关于这个,强烈大家去看一下Android文档。呃呃,相信在这个快速开发为王道的环境,没几个人会去看,所以还是在这里简单介绍一下。
阿利民
2022-05-16
6120
「Android音视频编码那点破事」第三章,使用OpenGL为Camera添加各种滤镜
  在第二章中,我们通过一个Camera SurfaceTexture纹理,把摄像头数据绘制到这个纹理上,同时TextureView的SurfaceTexture纹理通过id与第一个纹理关联起来,从而把摄像头画面直接绘制到屏幕上。   对OpenGL有一定了解的人可能会知道,要使用OpenGL渲染各种好看的特效,FBO必不可少。通过FBO,我们可以先把摄像头数据绘制到Camera SurfaceTexture纹理上,然后把这个纹理数据再绘制到一个离屏的FBO,我们可以在这个FBO上做各种特效处理,处理完之后再把离屏FBO中的数据绘制到TextureView的SurfaceTexture纹理,也就是手机屏幕上。
阿利民
2022-05-16
5800
「Android音视频编码那点破事」第二章,使用TextureView渲染Camera画面
  上一章我们讲到了使用SurfaceTexture作为Camera数据的缓冲区,这仅仅是把帧数据缓冲到了纹理上,并没有把它绘制出来,所以这一章我们来实现这个功能。
阿利民
2022-05-16
1.1K0
点击加载更多
社区活动
腾讯技术创作狂欢月
“码”上创作 21 天,分 10000 元奖品池!
Python精品学习库
代码在线跑,知识轻松学
博客搬家 | 分享价值百万资源包
自行/邀约他人一键搬运博客,速成社区影响力并领取好礼
技术创作特训营·精选知识专栏
往期视频·千货材料·成员作品 最新动态
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档