跨系统的录音格式兼容性问题: iOS Android

Posted TonyHo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨系统的录音格式兼容性问题: iOS Android相关的知识,希望对你有一定的参考价值。

ios/ OS X支持的可播放的Audio Format与android支持的有些不一样。因此可能出现在Android设备上面使用MediaRecorder录制出来的音频文件在iOS上面不可用。当然也可能iOS上面录制的audio file在Android上面无法playback。

如果在iOS和Android上面开发类似微信这样的待遇语音交流的软件,那么就需要考虑iOS和Android上面录制出来的音频的跨系统的兼容性。

音频文件的基础知识

这方面涉及到下面几个方面:

  1. 采样率
  2. 比特率
  3. 声音通道
  4. 编码格式:指压缩方法
  5. 存储容器:即压缩后使用什么方式存储

对于这些可以看文章:How to convert between (most) audio formats in .NET


不同系统对音频的支持

iOS OS X支持的格式

找到Apple Developer的文档页面,或者google “iOS Audio Support Format”,可以看到apple的系统支持的格式如下。

File Format

Data Formats

AAC (.aac, .adts)

'aac '

AC3 (.ac3)

'ac-3'

AIFC (.aif, .aiff,.aifc)

BEI8, BEI16, BEI24, BEI32, BEF32, BEF64, 'ulaw', 'alaw', 'MAC3', 'MAC6', 'ima4' , 'QDMC', 'QDM2', 'Qclp', 'agsm'

AIFF (.aiff)

BEI8, BEI16, BEI24, BEI32

Apple Core Audio Format (.caf)

'.mp3', 'MAC3', 'MAC6', 'QDM2', 'QDMC', 'Qclp', 'Qclq', 'aac ', 'agsm', 'alac', 'alaw', 'drms', 'dvi ', 'ima4', 'lpc ', BEI8, BEI16, BEI24, BEI32, BEF32, BEF64, LEI16, LEI24, LEI32, LEF32, LEF64, 'ms\\x00\\x02', 'ms\\x00\\x11', 'ms\\x001', 'ms\\x00U', 'ms \\x00', 'samr', 'ulaw'

MPEG Layer 3 (.mp3)

'.mp3'

MPEG 4 Audio (.mp4)

'aac '

MPEG 4 Audio (.m4a)

'aac ', alac'

NeXT/Sun Audio (.snd, .au)

BEI8, BEI16, BEI24, BEI32, BEF32, BEF64, 'ulaw'

Sound Designer II (.sd2)

BEI8, BEI16, BEI24, BEI32

WAVE (.wav)

LEUI8, LEI16, LEI24, LEI32, LEF32, LEF64, 'ulaw', 'alaw'

Key for linear PCM formats. For example, BEF32 = Big Endian linear PCM 32 bit floating point. 


Android支持的格式

参考Android开发者手册可以获取下面的内容

Format / CodecEncoderDecoderDetailsSupported File Type(s) / Container Formats
AAC LCSupport for mono/stereo/5.0/5.1content with standard sampling rates from 8 to 48 kHz.• 3GPP (.3gp)
• MPEG-4 (.mp4, .m4a)
• ADTS raw AAC (.aac, decode in Android 3.1+, encode in Android 4.0+, ADIF not supported)
• MPEG-TS (.ts, not seekable, Android 3.0+)
HE-AACv1 (AAC+)
(Android 4.1+)
HE-AACv2 (enhanced AAC+) Support for stereo/5.0/5.1content with standard sampling rates from 8 to 48 kHz.
AAC ELD (enhanced low delay AAC)
(Android 4.1+)

(Android 4.1+)
Support for mono/stereo contentwith standard sampling rates from 16 to 48 kHz
AMR-NB4.75 to 12.2 kbps sampled @ 8kHz3GPP (.3gp)
AMR-WB9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz3GPP (.3gp)
FLAC 
(Android 3.1+)
Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1kHz is recommended on devices with 44.1 kHz output, as the 48 to 44.1 kHzdownsampler does not include a low-pass filter). 16-bit recommended;no dither applied for 24-bit.FLAC (.flac) only
MIDI MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody• Type 0 and 1 (.mid, .xmf, .mxmf)
• RTTTL/RTX (.rtttl, .rtx)
• OTA (.ota)
• iMelody (.imy)
MP3 Mono/Stereo 8-320Kbps constant (CBR) or variable bit-rate (VBR)MP3 (.mp3)
Opus 
(Android 5.0+)
 Matroska (.mkv)
PCM/WAVE
(Android 4.1+)
8- and 16-bit linear PCM (rates up to limit of hardware). Samplingrates for raw PCM recordings at 8000, 16000 and 44100 Hz.WAVE (.wav)
Vorbis  • Ogg (.ogg)
• Matroska (.mkv, Android 4.0+)

这里列举了Encoder和Decoder,分别对应到录音和播放。

因此我们的问题就变成了哪种/哪些Encoder是是在iOS和Android都支持的?

选择

我们可以看到AAC 编码 + MPEG-4 容器,是两个系统都支持的,那么可选择这个。

Android中可以使用MediaRecorder来完成声音的录制加编码处理,也可以使用底层的接口录制出PCM未压缩的格式,然后使用第三方库来进行编码。


在StackOverFlow中对此有回答(audio format for iOS and Android),经过个人验证,其实可以在Android端录制后取得后缀名为.m4a那么在iOS中也可以播放:



更进一步,在github找了个soundRecord apk源码,只需要做个简单的修改然后就可以用来验证:

$ git diff
diff --git a/app/src/main/java/com/danielkim/soundrecorder/RecordingService.java b/app/src/main/java/com/danielkim/soundrecorder/RecordingService.java
index a8b36a1..e5047bb 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/RecordingService.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/RecordingService.java
@@ -112,9 +112,9 @@ public class RecordingService extends Service 
             count++;
 
             mFileName = getString(R.string.default_file_name)
-                    + "_" + (mDatabase.getCount() + count) + ".mp4";
+                    + "_" + (mDatabase.getCount() + count) + ".m4a";
             mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
-            mFilePath += "/SoundRecorder/" + mFileName;
+            mFilePath += "/TonyHo/" + mFileName;
 
             f = new File(mFilePath);
         while (f.exists() && !f.isDirectory());


参考

1. NAudio

1.1  讲解:关于使用.Net来做Audio Encoder/Decoder的文章

1.2 NAudio Github

2. 格式转换与查看工具lameXPLameXP


以上是关于跨系统的录音格式兼容性问题: iOS Android的主要内容,如果未能解决你的问题,请参考以下文章

APICloud开发者进阶之路 |audioRecorder录音模块Demo

js的new Date兼容iOS和Android

vue 公众号H5 使用微信JSAPI 录音 完整齐全

跨操作系统的代码为什么不兼容

html(JS,JQUERY)怎么播放amr格式的音频

IOS中重复音频的损坏录音