ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Android音视频开发面试核心考点:从MediaCodec到播放器架构

Android音视频开发面试核心考点:从MediaCodec到播放器架构 最近在帮团队做Android音视频开发的面试复盘筛了三十多份简历、面了十几位候选人发现一个很普遍的现象很多人简历上写着“熟悉MediaCodec、了解FFmpeg”但一追问到I帧P帧的区别、时间戳怎么对齐、硬解黑屏怎么降级就开始含糊其辞。音视频这块内容又多又杂网上资料大多是复制粘贴的API文档真正能把原理讲透、把坑说清的面试题整理反而很少。这篇文章我打算换个角度来写不按“基础知识—框架—实战”这种教科书式顺序而是把面试官真正会追问的考点逐个拆开从底层概念一路聊到播放器架构和性能优化。无论你是刚准备转音视频方向的学生还是已经写了几年业务、想往多媒体底层深挖的Android开发都可以拿这篇做一份对照自查清单。1. 音视频基础概念面试官最爱往深里问的知识点音视频面试第一关往往是基础概念但这里有个陷阱大多数人都能说个大概可一旦面试官开始追问“为什么”和“怎么算”就露馅了。1.1 采样、量化、编码底层的三步曲任何模拟信号要变成数字信号都要经过采样、量化、编码三个过程。声音的采样是把连续的声波在时间轴上离散化图像的采样是在空间轴上离散化采样率决定了时间/空间的细腻程度量化则是把连续的幅度值映射到有限个离散等级位深决定了精度编码是在数字化的基础上做压缩去掉冗余信息。面试时如果只答到这里大概是及格分。想拿高分必须把几个关键参数挂上钩音频采样率44100Hz是CD标准48000Hz是视频制作常用标准Android原生播放器对48000Hz的支持更好。位深16bit每样本是常规水平24bit以上常用于专业录音位深越大动态范围越好但数据量也线性增长。视频的采样更像是对每个像素的亮度和色度分别采样YUV420格式里每4个亮度样本共享一组色度样本这直接决定了视频编码前的数据量。一个简单的计算一秒钟未经压缩的48kHz、16bit、双声道音频数据量是48,000 × 16 / 8 × 2 192,000字节约187.5KB。而一秒钟1080p30帧的YUV420原始视频每帧像素为1920×1080×1.5字节约2.9MB再加上帧率就是每秒91MB。当你把这两个数字摆出来面试官就知道你是真的理解数据量概念而不是背了公式。1.2 I帧、P帧、B帧和GOP别只背名字视频编码里最重要的概念之一就是帧类型。I帧是关键帧包含完整画面信息解码时不依赖其他帧P帧是前向预测帧只保存和前一帧的差值B帧是双向预测帧同时参考前后帧。GOP是两个I帧之间的完整帧序列GOP越长压缩率越高但随机访问能力越差。面试官问到这里通常会跟进一个问题GOP设置多大合适这个问题没有标准答案取决于场景。直播场景要求低延迟GOP一般设置1到2秒这样关键帧间隔短观众拖到任意位置都能快速出画面点播场景追求压缩率GOP可以放到4到5秒甚至更长。GOP越长同码率下画质越好但遇到丢包时画面花屏的恢复时间也越长。还有一类特殊场景是视频剪辑如果GOP里有B帧切割点不在I帧上就会导致解码困难所以剪辑工具的转码服务通常会强制关闭B帧。这里有一个我在实际对接播放器时踩过的坑很多视频网站的CDN切流、广告插入都依赖GOP对齐。如果编码器输出的GOP没有设置为固定大小观众在观看时一旦发生码流切换画面大概率会先花掉一两秒。所以在做HLS切片或者直播转码时一定要确认编码器设置的GOP大小是固定的而不是“自适应”。1.3 DTS和PTS音视频同步的关键DTS是解码时间戳表示数据包什么时候应该被解码PTS是显示时间戳表示解码后的帧什么时候应该被渲染。在有B帧的场景里解码顺序和显示顺序是不一致的所以必须有这两个时间戳来分别指导解码器和渲染器。举个具体例子一个GOP的帧顺序是I帧、B帧、P帧、B帧、P帧解码顺序是I、P、B、P、B而显示顺序是I、B、P、B、P。如果只用PTS来驱动解码器解码器根本没法工作因为B帧的解码依赖后面的P帧。所以在做播放器时喂给解码器的顺序必须按DTS排好渲染时再根据PTS对齐。时间戳的精度也是面试高频点。Android里MediaCodec输出的时间戳单位是微秒而很多封装格式用的是毫秒。换算过程中最忌讳用整型除法直接截断否则长时间播放后音画偏移会越积越大。我之前见过一个播放器项目音频时间戳做了毫秒到微秒的乘法视频时间戳没做播到半小时后声音比画面快了近一秒。这种问题靠日志排查很难发现最后是拉长时间对比两个时间戳曲线才定位到。1.4 码率、帧率、分辨率换算关系要心里有数这三个参数的关系就是码率 每帧平均字节数 × 帧率 × 8。给定码率和帧率可以反推每帧的数据预算。1080p30、H.264编码要想画面干净码率大概需要4到8Mbps。如果码率给到2Mbps画面静止时还行一动起来就会出现块效应和边缘振铃。面试官有时候会故意问同样分辨率为什么H.265比H.264省一半码率本质是H.265引入了更灵活的块划分CU/PU/TU和更精细的帧内预测模式在相同感知画质下能用更少的比特描述像素块。还有一个容易忽略的点是帧率并不是越高越好。高帧率意味着单帧的编码预算被压缩如果码率不变从30fps提到60fps单帧画质反而下降。所以做视频录制类App时帧率和码率需要一起调不能只动一个参数。2. Android媒体组件底细MediaCodec、Extractor、Muxer、Render基础概念过关后面试官基本就会把话题拉到Android平台上考察你对官方多媒体组件的熟悉程度。这一轮是分辨“真用过”和“背过文档”的关键环节。2.1 MediaCodec状态机照背会翻车MediaCodec是Android音视频硬编硬解的核心API但要真正用好它必须清楚它的状态机。它大体上有Stopped、Executing、Released三个大状态其中Executing里又分Flushed、Running、End-of-Stream三个子状态。面试官最常见的考法是你向一个刚启动的MediaCodec提交InputBuffer为什么会返回错误因为你没有等待它进入Running状态。正确的做法是循环查询状态判断返回值是INFO_TRY_AGAIN_LATER还是BUFFER_FLAG_END_OF_STREAM再决定是继续投递还是走结束流程。还有一个大数据开发者不太注意的细节MediaCodec有两种操作模式同步模式和异步模式。同步模式用dequeueInputBuffer/dequeueOutputBuffer循环驱动逻辑清晰但线程管理麻烦异步模式通过回调通知输入输出代码更优雅但对状态机理解要求更高。新项目我更推荐异步模式回调里用HandlerThread串行处理能避免大量并发问题。这里顺便补充一个我在硬解时遇到的真实case某型号的芯片在解码H.264 High Profile视频时偶发绿屏log里没有异常后来发现是MediaCodec创建时没有显式设置KEY_PROFILE和KEY_LEVEL。个别厂商的底层实现不会从码流里自动探测Profile必须由上层指定。从那以后我在所有硬解初始化里都会带上Profile和Level兼容性问题少了一大半。2.2 MediaExtractor与MediaMuxer封装和解封装不容易MediaExtractor负责从文件里读取出音视频数据MediaMuxer负责把编码后的数据写回容器。把这两个组件分开考查是因为很多做播放器的人只用了MediaExtractor没写过MediaMuxer而做录制功能的人恰恰反过来。我在面试里喜欢问一个综合题如果要实现一个MP4转TS的工具需要怎么设计核心答案是用MediaExtractor按帧读取出H.264 Annex-B码流转换成AVCC格式后再用MediaMuxer写入MP4。反过来从MP4转到TS需要重新解析NALU添加PPS/SPS和SEI。这个过程中MediaExtractor输出的CSD信息Codec Specific Data非常重要丢失了它解码器根本无法初始化。实际操作中MediaMuxer还有个限制MP4格式要求写入的sample必须按PTS单调递增。如果你的编码器输出了B帧编码顺序和显示顺序不一致直接写入会报错。这就要在Muxer前做一个帧排序。我在某个录制模块里就因为这个原因踩过坑最后用优先级队列按PTS排好序才解决。封装格式的差异也是面试官爱问的点比如MP4和FLV的区别、TS切片时长怎么选。MP4适合点播因为moov box可以在文件头方便拖拽FLV适合直播因为结构简单、支持流式写入TS适合HLS切片因为天生支持多路音视频复用。这些封装层面的知识在工作里真正碰到的时候才知道有多重要。2.3 SurfaceView、TextureView和GLSurfaceView选型不是拍脑袋做播放器或相机预览一定会遇到View选型问题。面试官考查的是你对渲染管线的理解而不是View本身。SurfaceView的特点是独立窗口它有独立的Surface可以跑到应用视图层级之后用独立的线程去做绘制。它的优点是效率高、内存占用低因为绘制不走应用GPU合成缺点是它不能做动画变形也没法被其他View遮挡最麻烦的是它不能在其他表面做分层动画。TextureView是把Surface包装在View体系内部需要走View的绘制流程所以能支持旋转、缩放、平移等动画。但它多了一次合成性能开销比SurfaceView大。Android 7.0之前TextureView还有一个致命问题就是无法在SurfaceView和TextureView之间无缝切换切换时会出现黑屏闪烁。GLSurfaceView是专门为OpenGL ES渲染设计的SurfaceView适合做滤镜、特效渲染。但它的生命周期和GL上下文绑定做复杂渲染时要注意GL线程和UI线程的同步。如果只是做一个简单播放器我的建议是优先SurfaceView如果要做贴纸、旋转、动画播放器选TextureView如果要做实时滤镜直接上GLSurfaceView。还有一种场景是录制屏幕或者沉浸式播放用TextureView配合MediaCodec的Surface输入模式更容易实现。2.4 AudioTrack与OpenSL ES声音输出不止一种方式面试时很多人谈音频只知道MediaPlayer但真正做底层音频播放一定会接触到AudioTrack和OpenSL ES。AudioTrack是Android上层API可以把PCM数据直接写到音频设备。用AudioTrack播放音频需要指定音频流类型STREAM_MUSIC、STREAM_VOICE_CALL等、采样率和声道格式。这里有个关键点AudioTrack也有一个缓冲区大小问题设置过小会导致播放卡顿设置太大会增加延迟。一般建议用AudioTrack.getMinBufferSize()拿到系统建议的最小缓冲长度再根据业务需要乘以2到3倍。OpenSL ES是C层API性能比AudioTrack好因为绕过了Java层的部分开销。很多跨平台播放器内核都使用OpenSL ES实现音频输出。面试如果聊到自研播放器这个话题是加分项但要说得清楚OpenSL ES的播放回调是直接从音频引擎的线程触发的在回调里不能做任何耗时操作否则会直接影响声音连续性。纹理上传、写日志、加锁这类操作都应该挪出去。3. 播放器架构与性能优化从能播到播得好播放器不只是MediaCodec加MediaPlayer一个完整的架构设计题可以考查从解协议、解封装、解码到渲染的整条链路。面试官在这块通常会问得很开放关键看你脑子里有没有一张完整的地图。3.1 播放器整体架构画出模块图一个标准的播放器包含数据读取模块DataSource、解封装模块Demuxer、解码模块Decoder、渲染模块Renderer和同步控制模块Sync。我在回答这类问题时会直接在白板上画出模块边界和数据流DataSource从本地文件或网络流读取字节交给Demuxer按封装格式拆帧得到编码后的音频包和视频包再分别送入音频解码器和视频解码器解码后的数据分别送到AudioTrack和Surface渲染同步模块通过PTS和系统时钟来对齐两条渲染链路。面试官紧接着就会问整个播放流程中哪些模块可以复用这就涉及到播放器分层设计了。我建议把数据源、解封装、解码收敛到播放内核层渲染和事件回调放在外层。内核层用C/C编写的好处是可以跨平台复用但缺点是和Java层的交互成本高要在JNI层做严格的数据拷贝控制。跨平台播放器这块是近几年的大热门像ExoPlayer本身就是Android平台内嵌的多媒体框架而IjkPlayer是FFmpeg的Android封装。两者对比下来ExoPlayer的优势是官方维护、协议支持完善、MediaCodec硬解适配好IjkPlayer的优势是媒体格式兼容性更强但项目维护趋于停滞。面试官问你这个对比更多是想了解你对社区生态的判断力。一个偏开放的追问自研播放器时你会用什么语言写核心我的答案始终是C/C加JNI核心编解码、网络协议、解封装全部下沉到C层Java只做生命周期管理和UI渲染。理由很简单移植性好、性能可控、调试方便。但这里要提醒一下要处理好Native崩溃的堆栈符号化否则线上问题完全无从下手。3.2 音视频同步的三种方案必须会推导音视频同步的经典解法是主时钟同步。选一种时间源作为主时钟其他媒体向它对齐。第一种方案以音频为主时钟这是最常见也最合理的选择。因为人耳对声音断断续续比画面跳帧更敏感音频播放的连续性要求极高。具体操作音频正常连续播放视频帧根据PTS与音频时钟的差值来决定是等待还是丢帧。如果视频帧比音频慢就延迟渲染如果视频帧比音频快太多就丢弃旧帧追赶上。第二种方案以视频为主时钟用于无声视频或音频数据严重缺失的场景此时画面连续性优先音频播放速度跟随视频节奏。第三种方案是外部时钟用系统单调时钟作为主参考音频和视频都向它对齐。这种方案适合音视频源来自不同时钟域的情况实现复杂度高。我面试时喜欢反着问如果音视频差了几十毫秒你会怎么办很多人第一反应是直接丢弃帧。这其实是不对的几十毫秒的偏移完全可以通过调整播放速率来纠正。Android 7.0之后可以通过AudioTrack.setPlaybackParams调整速度ExoPlayer里也有PlaybackParameters可以实现变速不变调。只有在偏移超过几百毫秒、无法通过速率微调纠正时才考虑清空缓冲重新对齐。同步策略其实是播放器里最考功力的一部分因为它涉及的不只是技术还有用户主观体验。我在做播放器调优时总结了一个阈值经验音频超前视频超过100ms用户就能察觉口型不对视频超前音频超过200ms用户会明显觉得画面跳。所以同步算法里建议设置两个不同的阈值一个用于触发等待一个用于触发丢帧。3.3 首屏秒开与卡顿优化实战味道很浓的问题首屏秒开几乎是每个音视频面试必问的实战题。面试官真正想听的是你有没有从整个链路做起而不是只盯着解码器。首屏耗时可以拆成网络请求耗时、数据下载耗时、解封装耗时、解码首帧耗时、渲染首帧耗时几个环节。常规优化手段包括DNS预解析和连接复用针对点播URL做DNS缓存减少HTTP DNS解析时间。请求Range分片不要等待整个文件头提前读到moov box的位置。解封装预热部分格式支持从文件尾部读取索引信息不用扫描全部数据。视频参数集缓存把SPS/PPS等参数提前缓存解码器初始化阶段不用再等待码流解析。预渲染解码出第一帧后马上丢到Surface不等第二帧。还有一种更激进的方案是做预加载比如在用户点击播放按钮前就提前缓存前几个分片。这个玩法我在短视频App里见过很多用户上下滑的时候候选视频已经被预下载了几百KB到几MB的数据真正播放时首帧几乎秒出。卡顿优化则是另一个大话题。网络卡顿要加缓存策略、段切换策略解码卡顿要检查解码器实例是否需要重建、输入缓冲区设置是否合理渲染掉帧要排查View类型和渲染链路。有一个容易被忽略的细节MediaCodec硬解在某些设备上会默认输出到Surface而非ByteBuffer如果后续要做OpenGL渲染就必须把它配置为Surface输入否则每帧拷回CPU内存的开销是灾难级的。3.4 硬解与软解的选择兼容性与功耗的平衡硬解和软解是播放器设计里绕不开的方向。硬解是用GPU或专门的DSP解码功耗低、性能高但兼容性差因为芯片厂商的驱动实现参差不齐。软解是用CPU跑FFmpeg解码兼容性最好但功耗高、发热大。我的经验是优先硬解但必须设计自动降级机制。具体流程是先用MediaCodec探支持能力如果当前视频的Profile/Level不被支持就自动切到软解。探支持能力不是写死一个list而是调用MediaCodecList的getSupportedTypes再配合MediaFormat的KEY_PROFILE和KEY_LEVEL做精确匹配。软解选择FFmpeg解码时值得注意的是多线程解码。FFmpeg对H.264/H.265都有多线程支持在Android上要合理设置thread_count过度增大线程数并不会线性提升性能反而增加线程切换开销。另外软解内存足迹也要关注软解1080p视频的缓冲区往往能撑到几十MB低端机容易OOM所以内存复用要做到极致。硬解黑屏是一个特别常见的面试场景题原因是Surface没有准备好就调用了start或者BufferQueue的生产者消费者不匹配。排查方式通常是先看MediaFormat里是否带CSD再检查Surface是否有效最后看SPS/PPS是否被正确传递。4. 采集、渲染与推流从本地播放延伸到实时场景播放之外采集和推流也是音视频面试的重要分支尤其在直播、短视频、视频会议这类场景里。4.1 Camera2 采集与预览链路Camera2是Android相机的新架构它把相机能力抽象成Pipeline通过CaptureRequest控制每一帧的采集参数。做Camera2采集最关键的是理解生命周期设备打开、会话创建、捕获请求、重复请求关闭。静态配置里有一组容易混淆的参数PREVIEW、RECORD、MAXIMUM分别对应不同分辨率的缓冲区。简单说预览用低分辨率降低延迟录制用高分辨率保证画质拍照用最大分辨率保留细节。如果你的应用需要同时支持这些场景那就要配置多个CaptureSession或者做动态切换。Camera2的采集回调有两种方式ImageReader的Surface形式和CameraCaptureSession.CaptureCallback的Bytes形式。ImageReader非常适合配合MediaCodec的Surface输入直接做硬编因为两者都在图形缓冲区上操作省去一次拷贝。面试追问里有个高频点相机预览卡顿怎么排查答案通常集中在三个方向第一是ImageReader的maxImages设置太小导致队列阻塞第二是GLSurfaceView的GL线程和Camera线程没有做背压第三是SurfaceView切后台时没有及时release。这些坑我在实际项目中都踩过逐一写上来的话能写一整篇。4.2 音频采集、降噪与回声消除音频采集主要用AudioRecord它输出PCM数据采样率、声道数、位深必须和编码器一致。很多面试者会忽略一个细节AudioRecord的buffer大小不能随意设置过小会导致丢数据过大会增加延迟。建议用getMinBufferSize()查系统建议值再往上加。做直播或实时通话不得不面对降噪NS和回声消除AEC。Android自带的Acoustic Echo Canceler和Noise Suppressor可以解决一部分场景但效果上限有限。更专业的方案是接第三方SDK比如WebRTC的音频处理模块。面试时如果聊到音频处理常见的实战题是为什么你在连麦房里听到自己的回声原因是本机扬声器放出的对方声音被麦克风重新采集如果不做AEC或者AEC参考信号延迟设置不对对方的每一句话都会以你自己的声音形式回传回去。排查思路是抓取播放和采集两条音频流对比延迟和频谱。4.3 OpenGL ES 渲染与滤镜滤镜是短视频、直播客户端最核心的视觉功能而滤镜的底层一定绕不开OpenGL ES。面试官问滤镜一般不是要你背API而是想看你有没有理解渲染管线。从相机采集到输出整个渲染链路是SurfaceTexture把Camera数据转成GL纹理然后经过FBO帧缓冲对象做滤镜处理最后渲染到屏幕。滤镜效果的本质是对纹理每个像素做片段着色器计算比如灰度滤镜就是把RGB三通道加权求和美颜滤镜则复杂得多涉及边缘保留滤波和肤色检测。GL纹理的坐标系和普通图片坐标系不一样纹理坐标原点在左下角。新手最容易犯的错误是纹理方向不对导致画面上下颠倒这也是相机预览常见的bug。解决方式是在绘制顶点前翻转纹理坐标。FBO的使用也是滤镜工程里的关键点。你要对纹理做多级处理不能直接在一个纹理上反复读写需要创建一个离屏FBO作为中间层。多层滤镜串联时每一层都需要独立的FBO否则会出现不可预期的叠加效果。4.4 直播推流协议选型RTMP、HLS、SRT直播推流协议也是面试官爱挖掘的点。RTMP基于TCP适合国内直播延迟2到5秒兼容性好但缺点是TCP在弱网下容易因为重传导致延迟升高。HLS基于HTTP延迟一般在5到15秒苹果生态和CDN支持好但延迟难降。SRT基于UDP专为弱网设计具备前向纠错延迟能控制在1秒内适合实时性要求极高的场景。如果面试官问你会怎么做直播选型我一般会答国内娱乐直播选RTMP因为CDN成熟、播放端兼容性广短视频点播走HLS因为切片天然适合CDN连麦或互动直播优先SRT或者WebRTC。有一个容易被忽略的点推流不是只推视频轨音频轨和视频轨的编码参数一定要匹配。常见的坑是音频采样率和视频GOP设置不一致导致推流服务端切片时音视频不同步。还有就是推流要设置合理的编码码率上限不然电视端观众收看时会反复缓冲。WebRTC也是这两年音视频面试的必聊话题但WebRTC和大多数客户端SDK不一样它是为实时通信设计的核心是P2P传输和拥塞控制。如果你只是在做直播用WebRTC可能并不合适因为它的媒体服务器部署成本和信令复杂度都很高。如果面试官问到回答时可以先区分场景再讲技术选型逻辑。5. 高频追问与避坑经验照着这个清单去梳前面的内容都掌握后最后一步是磨面试技巧。音视频面试的特点是面试官喜欢从一个点切入然后层层深入直到问到你不会为止。所以重要的不是背题而是把每个回答变成可拓展的树状结构。5.1 高频追问一MediaCodec的InputBuffer里到底装的是什么这是最容易翻车的问题之一。很多人答“装的是编码后的数据”但这个答案太粗糙。实际上MediaCodec的输入Buffer里装着的是封装层解出来的sample它可能包含SPS/PPS这种参数集也可能包含一帧完整的编码数据。更严格地说MediaCodec需要一个完整AUsAccess Unit作为一次输入。如果你把半个NALU塞进去解码器直接报错。这里有一个实操经验很多H.264码流在输入MediaCodec之前需要把Annex-B格式转成AVCC格式。MediaCodec在Android API 21以前只接受AVCC21以后能识别Annex-B里的起始码并做内部转换。所以如果你在低版本设备上硬解失败优先检查码流封装格式。5.2 高频追问二硬解失败后怎么办这个问题几乎没有标准答案但面试官想听的是你的降级方案硬解失败的第一反应是捕获MediaCodec.CodecException区分是资源不足、格式不支持还是驱动崩溃。资源不足可以释放其他实例后重试格式不支持就直接切软解驱动崩溃则需要做实例重建有些情况下要重启进程才能恢复。软解方案也不是简单的new一个解码器需要考虑数据格式兼容、耗时控制、内存管控。我通常会建立一份“硬解失败视频特征”的日志表记录分辨率、编码格式、Profile、Level、设备型号方便后续做针对性适配。5.3 常见问题排查速查表整理一份我在项目里常见的音视频问题排查表面试时能背出这些经验是非常加分的问题现象可能原因排查方法视频起播黑屏未传CSD/SPS/PPSSurface未就绪检查MediaFormat的csd-0/csd-1打印Surface状态音画不同步时间戳换算错误同步时钟选择不对对比音视频PTS曲线检查校准逻辑硬解花屏/绿屏Profile/Level不支持码流标头丢失用MediaCodecList探测能力抓流分析NALU播放卡顿网络缓冲不足解码器阻塞掉帧策略不对统计buffer水位、Jank/FPS曲线内存持续上涨Buffer没释放GL纹理泄漏用Memory Profiler和OpenGL debug输出查纹理数量声音断断续续AudioTrack缓冲区过小回调线程阻塞增大缓冲检查AudioTrack回调耗时推流延迟越拉越大TCP重传拥塞GOP设置过大改用UDP/SRT调整GOP时长首帧很慢网络DNS慢moov box在文件尾解码器热启动慢DNS预解析让服务端把moov移到文件头解码器实例缓存5.4 简历与复习建议最后说说简历和复习策略。音视频方向的简历我建议一定要写出能证明你做过的事比如实现的播放器能做到多少分辨率的硬解、首屏耗时控制在多少、推流延迟能达到多少秒。这些数字远比“熟悉音视频开发”有说服力。复习的时候不要只刷题按“底层原理—平台API—项目实战—优化案例”四个层次整理自己的知识树。每复习一个点就尝试引导面试官朝你最熟悉的方向提问比如你提到正在做直播面试官大概率会追问推流协议、编码参数和延迟优化。提前准备好深挖的数据才是制胜关键。我个人的体会有两点一是音视频领域最值钱的能力不是背API而是调试能力。出问题能快速定位到链路哪一环比能默写十个函数名强得多。二是所有理论知识如果不能落到自己电脑上跑一遍面试时一旦被连续追问就会露怯。建议找一段公开的MP4视频用Android Studio起个项目从MediaExtractor拉到MediaCodec硬解再到AudioTrack和Surface播放亲手跑通一个最简单的播放器这套流程走完面试中绝大多数问题都能接得住。
返回列表