Android 播放opus格式的音频

文章目录

      • Opus简介
      • 技术特性
      • Opus 标识头
      • Android播放opus
        • 原生播放
        • 三方播放器播放
          • 本地导入ExoPlayer
          • 本地打包opus的so库
          • 调用

Opus简介

Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务组进行标准化,目标是希望用单一格式包含声音和语音,取代Speex和Vorbis,且适用于网络上低延迟的即时声音传输,标准格式定义于RFC 6716文件。Opus格式是一个开放格式,使用上没有任何专利或限制。

在官方的example测试案例中,就算有30%的丢包率,也能够听清楚人声,这对于即时的声音传输场景来说非常重要。并且它支持动态、无缝的调节比特率与音频带宽,在网络环境多变的场景下更能保证音频的质量。

同时它是WebRTC中默认的音频编码格式、也是WebM视频文件中音频的编码格式。

技术特性

Opus可以处理各种音频应用,包括IP语音、视频会议、游戏内聊天、流音乐、甚至远程现场音乐表演。它可以从低比特率窄带语音扩展到非常高清音质的立体声音乐。支持的功能包括:

  • 6 kb/秒到510 kb/秒的比特率;单一频道最高256 kb/秒
  • 采样率从8 kHz(窄带)到48 kHz(全频)
  • 帧大小从2.5毫秒到60毫秒
  • 支持恒定比特率(CBR)、受约束比特率(CVBR)和可变比特率(VBR)
  • 支持语音(SILK层)和音乐(CELT层)的单独或混合模式
  • 支持单声道和立体声;支持多达255个音轨(多数据流的帧)
  • 可动态调节比特率,音频带宽和帧大小
  • 良好的鲁棒性丢失率和数据包丢失隐藏(PLC)
  • 浮点和定点实现

Opus 标识头

关于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个参数组成,分别为:

  • Magic Signature:固定头,占8个字节,为字符串OpusHead
  • Version:版本号,占1字节,固定为0x01
  • Channel Count:通道数,占1字节,根据音频流通道自行设置,如0x02
  • Pre-skip:回放的时候从解码器中丢弃的samples数量,占2字节,为小端模式,默认设置0x00, 0x00
  • Input Sample Rate (Hz):音频流的Sample Rate,占4字节,为小端模式,根据实际情况自行设置
  • Output Gain:输出增益,占2字节,为小端模式,没有用到默认设置0x00, 0x00
  • Channel Mapping Family:通道映射系列,占1字节,默认设置0x00
  • Channel Mapping Table:可选参数,上面的Family默认设置0x00的时候可忽略

Android播放opus

原生播放

从Android 5.0+开始,官方支持opus解码 这意味着 MediaPlayer即可播放opus音频流。

三方播放器播放

ExoPlayer也支持播放opus

本地导入ExoPlayer

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')
本地打包opus的so库

按此操作

调用
  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);

你可能感兴趣的:(android,android,音频播放,opus,Exoplayer)