Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务组进行标准化,目标是希望用单一格式包含声音和语音,取代Speex和Vorbis,且适用于网络上低延迟的即时声音传输,标准格式定义于RFC 6716文件。Opus格式是一个开放格式,使用上没有任何专利或限制。
在官方的example测试案例中,就算有30%的丢包率,也能够听清楚人声,这对于即时的声音传输场景来说非常重要。并且它支持动态、无缝的调节比特率与音频带宽,在网络环境多变的场景下更能保证音频的质量。
同时它是WebRTC中默认的音频编码格式、也是WebM视频文件中音频的编码格式。
Opus可以处理各种音频应用,包括IP语音、视频会议、游戏内聊天、流音乐、甚至远程现场音乐表演。它可以从低比特率窄带语音扩展到非常高清音质的立体声音乐。支持的功能包括:
关于Opus的标识头,可以从rfc7845标准文档中找到详细的解答,格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'O' | 'p' | 'u' | 's' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'H' | 'e' | 'a' | 'd' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version = 1 | Channel Count | Pre-skip |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Input Sample Rate (Hz) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Output Gain (Q7.8 in dB) | Mapping Family| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ :
| |
: Optional Channel Mapping Table... :
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2: ID Header Packet
Identification header主要由8个参数组成,分别为:
从Android 5.0+开始,官方支持opus解码 这意味着 MediaPlayer即可播放opus音频流。
ExoPlayer也支持播放opus
Cloning the repository and depending on the modules locally is required when using some ExoPlayer extension modules. It’s also a suitable approach if you want to make local changes to ExoPlayer, or if you want to use a development branch.
First, clone the repository into a local directory and checkout the desired branch:
git clone https://github.com/google/ExoPlayer.git
cd ExoPlayer
git checkout release-v2
Next, add the following to your project’s settings.gradle
file, replacing path/to/exoplayer with the path to your local copy:
gradle.ext.exoplayerRoot = 'path/to/exoplayer'
gradle.ext.exoplayerModulePrefix = 'exoplayer-'
apply from: new File(gradle.ext.exoplayerRoot, 'core_settings.gradle')
You should now see the ExoPlayer modules appear as part of your project. You can depend on them as you would on any other local module, for example:
implementation project(':exoplayer-library-core')
implementation project(':exoplayer-library-dash')
implementation project(':exoplayer-library-ui')
按此操作
LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
player = new ExoPlayer.Builder(context, audioRenderer).build();
player.addListener(this);
MediaSource mediaSource =
new ProgressiveMediaSource.Factory(
new DefaultDataSourceFactory(context, "ExoPlayerExtOpusTest"),
MatroskaExtractor.FACTORY)
.createMediaSource(uri);
player.prepare(mediaSource);
player.setPlayWhenReady(true);