一种Linux平台上安卓应用低延迟音频输出方法与流程
一种linux平台上安卓应用低延迟音频输出方法
技术领域
1.本发明属于桌面操作系统上运行移动应用的开发技术领域,具体涉及一种linux平台上安卓应用低延迟音频输出方法。
背景技术:
2.音频
一种linux平台上安卓应用低延迟音频输出方法 技术领域 1.本发明属于桌面操作系统上运行移动应用的开发技术领域,具体涉及一种linux平台上安卓应用低延迟音频输出方法。 背景技术: 2.音频数据处理是安卓系统非常重要的组成部分,负责音频数据的采集和输出、音频流的控制、音频设备的管理及音量调节等,主要包括音频应用框架(audio application framework)、音频本地框架(audio native framework)、音频服务(audio services)和音频硬件抽象层(audio hal)。此外,与音频数据处理强相关的有 multimedia,multimedia 负责音视频的编解码,multimedia 将解码后的数据通过 audiotrack 输出,而 audiorecord 采集的录音数据交由 multimedia 进行编码。 3.一般情况下,安卓系统中安卓应用播放音频可采用mediaplayer 和 audiotrack。其中,mediaplayer支持播放多种格式的音源,如:mp3、flac、wma、ogg、wav等,mediaplayer的实现过程中先在 native 层创建对应的音频解码器和audiotrack,并将由音频解码器解码后的数据交由audiotrack进行输出,由此可见,mediaplayer的应用场景更广使用也更方便。audiotrack仅支持播放解码后的 pcm 数据流,通常在对声音时延要求非常苛刻的应用场景才需要用到audiotrack。 4.安卓系统中安卓应用播放音频的过程为:mediaplayer解析音频文件格式,然后调用解码器生成pcm格式音频数据,再将pcm音频数据传输给audiotrack;audiotrack将音频数据传输给audioflinger;audioflinger混音后调用音频设备的hal接口,由音频设备的hal接口操作音频设备输出音频。 5.综上所述,由于安卓系统中安卓应用输出音频的操作过程所涉及的中间层、进程较多,音频数据处理流程较为复杂,数据传输过程的开销较大,因此导致安卓应用的音频输出效率较低,输出延时较大,很大程度上影响用户体验,现有运行于linux平台上的安卓兼容环境内一般是基于安卓系统的音频输出机制实现的安卓应用的音频输出,因此仍存在上述问题。 技术实现要素: 6.有鉴于此,本发明提供了一种linux平台上安卓应用低延迟音频输出方法,能够针对不同的音频播放器及不同的音频文件输出标识动态确定音频输出方式从而实现低延迟的音频输出。 7.本发明提供的一种linux平台上安卓应用低延迟音频输出方法,包括以下步骤:步骤1、安卓应用需要输出音频时,若当前安卓兼容环境中不存在其他安卓应用正在输出音频,则安卓应用获取音频焦点执行步骤2;否则执行步骤6;步骤2、若安卓应用采用mediaplayer输出音频则执行步骤3,若安卓应用采用audiotrack输出音频则执行步骤4; 步骤3、读取待输出音频后,采用解码器逐帧解码待输出音频得到解码音频文件,再基于pulseaudio接口逐帧将解码音频文件输出到linux音频设备,在安卓应用完成音频输出后执行步骤5;步骤4、读取待输出音频获取其输出标识,根据输出标识输出待输出音频,在安卓应用完成音频输出后执行步骤5;步骤5、安卓应用释放音频焦点,并检测安卓兼容环境内的暂停音频流队列,如果暂停音频流队列中存在被暂停的音频流,则选取暂停音频流队列中最早暂停的音频流继续播放,结束本流程;如果没有,则结束本流程;步骤6、安卓应用请求获取音频焦点,若安卓应用未能获取音频焦点,则等待设定时间间隔后执行步骤6;若安卓应用获取了音频焦点,则暂停当前音频的输出,并等待当前音频解码完毕后,将当前音频作为暂停音频流追加到安卓兼容环境的暂停音频流队列中,执行步骤2。 8.进一步地,所述步骤3中基于解码器逐帧解码待输出音频得到解码音频文件,再基于pulseaudio接口逐帧将解码音频文件输出到linux音频设备包括:将待输出音频读入内存缓冲区;采用解码单元从内存缓冲区逐帧读取待输出音频并解码得到解码音频文件,将解码音频文件写入解码内存缓冲区后;再使用输出单元从解码内存缓冲区中读取解码音频文件,并根据码率确定输出间隔,按照输出间隔采用pulseaudio接口逐帧输出到linux音频设备。 9.进一步地,所述解码单元及输出单元均为以native函数的方式实现。 10.进一步地,在所述将待输出音频读入内存缓冲区之前,根据待输出音频的数据源确定待输出音频的类型,若待输出音频的类型为本地音频文件,则将本地音频文件一次性读入内存缓冲区,再根据音频文件的编码格式、压缩比及编码文件大小确定音频文件解码后的解码音频文件大小,根据解码音频文件大小分配用于存放解码音频文件的解码内存缓冲区;若待输出音频为网络音频流,则将待输出音频逐帧读入内存缓冲区。 11.进一步地,所述按照输出间隔采用pulseaudio接口逐帧输出到linux音频设备时采用linux系统的计时器接口进行计时。 12.进一步地,所述步骤4中根据输出标识输出待输出音频包括:当输出标识为audio_output_flag_direct时,采用alsa接口将待输出音频输出至linux音频设备;当输出标识为audio_output_flag_primary时,将待输出音频发送至audioflinger;当输出标识为audio_output_flag_fast时,若安卓应用以独占方式使用alsa接口则采用alsa接口将待输出音频输出至linux音频设备;否则采用pulseaudio将待输出音频输出至linux音频设备;当输出标识为audio_output_flag_deep_buffer时,采用pulseaudio将待输出音频输出至linux音频设备;当输出标识为audio_output_flag_compress_offload时,采用解码器解码待输出音频得到解码音频文件,若安卓应用以独占方式使用alsa接口则采用alsa接口将待输出音频输出至linux音频设备;否则采用pulseaudio将待输出音频输出至linux音频设备。 13.有益效果:本发明通过获取linux系统中安卓兼容环境中安卓应用所采用的音频播放器的类型确定音频的输出方式,且不同的输出方式均有效减少了安卓应用在音频播放过程所涉及的进程,缩减了进程间的数据交互,有效提高了安卓应用的音频输出效率,降低了输出延时,改善了用户体验。 附图说明 14.图1为本发明提供的一种linux平台上安卓应用低延迟音频输出方法的流程图。 具体实施方式 15.下面结合附图并举实施例,对本发明进行详细描述。 16.本发明提供了一种linux平台上安卓应用低延迟音频输出方法,其核心思想是:根据linux系统内安卓兼容环境中输出音频的情况,确定当前待播放音频的安卓应用获取焦点,再根据安卓应用所采用的音频播放器的不同完成安卓应用对音频的输出。 17.本发明提供了一种linux平台上安卓应用低延迟音频输出方法,流程如图1所示,具体包括以下步骤:步骤1、在linux系统的安卓兼容环境中,当安卓应用需要输出音频,则检测当前安卓兼容环境中是否存在正在输出音频的其他安卓应用,若当前安卓兼容环境中不存在其他安卓应用正在输出音频,则执行步骤2;若当前安卓兼容环境中存在其他安卓应用正在输出音频,则执行步骤6。 18.安卓兼容环境中安卓应用一般采用mediaplayer 和 audiotrack,但是底层都是采用audiomanagerservice创建的audiotrack输出音频,通过检测audiotracke的使用情况即可确定安卓兼容环境中是否存在安卓应用正在输出音频。 19.安卓系统中定义了以下六种类型的音频流,包括:audio_stream_voice_call为电话语音;audio_stream_system为系统声音;audio_stream_ring为铃声声音,如来电铃声、闹钟铃声等;audio_stream_music为音乐声音;audio_stream_alarm为警告音;audio_stream_notification为通知音;audio_stream_dtmfdtmf 为拨号盘按键音。 20.本发明仅针对其中的audio_stream_music音乐声音类型进行处理。 21.进一步地,当音频类型为audio_stream_music类型时,由于此类音频的时长往往较长,且码率较高,因此此类音频对延迟更加敏感,因此音频类型为audio_stream_music类型时处理效果更佳。 22.步骤2、安卓应用向安卓兼容环境发送requestaudiofocus消息获取音频焦点(audio focus),若安卓应用采用mediaplayer输出音频则执行步骤3,若安卓应用采用audiotrack输出音频则执行步骤4。 23.步骤3、读取待输出音频后,基于解码器逐帧对待输出音频解码得到解码音频文 件,再基于pulseaudio接口逐帧将解码音频文件输出到linux音频设备,在安卓应用完成音频输出后执行步骤5。 24.其中,读取待输出音频后,基于解码器逐帧对待输出音频解压得到解码音频文件,再基于pulseaudio接口逐帧将解码音频文件输出到linux音频设备,包括以下步骤:步骤3.1、获取安卓应用待输出音频的数据源,根据数据源判断待输出音频的类型,若待输出音频为本地音频文件,则将本地音频文件读入内存缓冲区,再根据音频文件的编码格式、压缩比及编码文件大小确定音频文件解码后的解码音频文件大小,根据解码音频文件大小分配用于存放解码音频文件的解码内存缓冲区;若待输出音频为网络音频流音频应用,则将待输出音频逐帧读入内存缓冲区。 25.在安卓兼容环境中,安卓应用往往通过setdatasource方法设置音频文件的来源,因此,本发明通过获取mediaplayer的data source即可判断音频文件的类型,例如,如果数据源是以、等开头则该音频文件属于网络音频流的类型,否则属于本地音频文件。 26.对于本地音频文件的类型,为了提高执行效率,本发明采用一次性将待输出音频读取到内存缓冲区中的方式,例如:使用内存缓冲区encodedaudiobuffer存储待输出音频,encodedaudiobuffer的大小为encodedaudiobuffersize,再根据待输出音频的音频文件编码格式及压缩比确定解码后音频文件的大小decodedaudiobuffersize,将解码音频文件存储在大小为decodedaudiobuffersize的内存缓冲区decodedaudiobuffer中。 27.具体来说,可采用decodedaudiobuffersize=encodedaudiobuffersize*(n+t)计算得到解码后音频文件的大小,其中,n(n》=1)为压缩比。 28.步骤3.2、采用解码单元从内存缓冲区逐帧读取待输出音频并解码得到解码音频文件,将解码音频文件写入解码内存缓冲区后,再使用输出单元从解码内存缓冲区中读取解码音频文件进行输出。解码单元及输出单元均为以native函数的方式实现的并行单元。 29.其中,解码单元用于解码待输出音频得到解码音频文件,再将解码音频文件写入解码内存缓冲区中;输出单元用于从内存缓冲区中逐帧读取解码音频文件,再采用pulseaudio接口逐帧输出解码音频文件。一般情况下,解码音频文件为pcm格式音频数据。 30.进一步地,本发明可以采用c/c++实现名为native_start的native函数,在native_start中创建两个线程解码线程和输出线程,分别负责解码音频数据和输出音频数据,即,分别实现解码单元和输出单元的功能。 31.解码线程利用ffmpeg或其他解码器逐帧解码待输出音频,即从encodedaudiobuffer中读取待输出音频并解码到decodedaudiobuffer,解码后的音频文件为pcm格式音频数据。输出线程根据码率确定输出间隔interval,为了进一步提高计时精度,本发明直接使用linux系统的计时器接口或者直接访问计时器寄存器,而不使用android系统的计时器接口,且每隔interval时间后从decodedaudiobuffer读取一帧数据再使用pulseaudio接口输出该帧数据,最后从decodedaudiobuffer中移除该帧数据。 32.步骤4、读取待输出音频,此时的待输出音频为解码后的解码音频文件,再获取audiotrack的输出标识,并根据输出标识对待输出音频进行分类处理以完成待输出音频的输出操作,在安卓应用完成音频输出后执行步骤5。 33.根据输出标识对待输出音频进行分类处理的过程具体包括: 当输出标识为audio_output_flag_direct时,则采用alsa接口将待输出音频输出至音频设备;当输出标识为audio_output_flag_primary时,则将待输出音频发送给audioflinger执行后续处理;当输出标识为audio_output_flag_fast时,若安卓应用能以独占方式打开alsa接口音频设备则采用alsa接口将待输出音频输出至音频设备,若安卓应用不能以独占方式打开alsa接口音频设备则采用pulseaudio将待输出音频输出至音频设备;当输出标识为audio_output_flag_deep_buffer时,则采用pulseaudio将待输出音频输出至音频设备;当输出标识为audio_output_flag_compress_offload时,则先采用解码器对待输出音频进行解码得到解码音频文件,若安卓应用能以独占方式打开alsa接口音频设备则采用alsa接口将待输出音频输出至音频设备,若安卓应用不能以独占方式打开alsa接口音频设备则采用pulseaudio将待输出音频输出至音频设备。 34.在现有安卓兼容环境中提供的audiotrack native api包括以下输出标识,安卓应用在采用音频播放器mediaplayer 和 audiotrack时将设定音频文件的输出标识:audio_output_flag_direct,表示音频流直接输出到音频设备,不需要软件混音,一般用于 hdmi 设备声音输出;audio_output_flag_primary,表示音频流需要输出到主输出设备,一般用于铃声类声音;audio_output_flag_fast,表示音频流需要快速输出到音频设备,一般用于按键音、游戏背景音等对时延要求高的场景;audio_output_flag_deep_buffer,表示音频流输出可以接受较大的时延,一般用于音乐、视频播放等对时延要求不高的场景;audio_output_flag_compress_offload,表示音频流没有经过软件解码,需要输出到硬件解码器,由硬件解码器进行解码。 35.进一步地,为了提高处理效率进一步降低延时,本发明提出的根据输出标识对待输出音频进行分类处理以完成待输出音频的输出操作是基于audiotrack的native api实现的。 36.步骤5、安卓应用释放audio focus,并检测安卓兼容环境内的暂停音频流队列,如果暂停音频流队列中存在被暂停的音频流,则从暂停音频流队列中取出最早暂停的音频流继续播放;如果没有,则结束本流程。 37.步骤6、安卓应用向安卓兼容环境发送requestaudiofocus消息,若安卓应用未能获取audio focus,则等待设定时间间隔后执行步骤6;若安卓应用获取了audio focus,则暂停当前的音频输出操作,并等待当前音频解码操作完成得到暂停音频流,将暂停音频流加入安卓兼容环境的暂停音频流队列中,执行步骤2。 38.综上所述,以上仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |