Android:在Android中录制音频然后将音频读入python

标签 android python-2.7 audio ffmpeg audio-recording

我需要在 Android 应用程序中录制音频,该应用程序需要导入到 Python (ndarray) 中以进行绘图和信号处理。这看起来是一个非常简单的想法。
我从一段简单的 AAC/MPEG4 录制代码开始。录音效果很好。我可以在 Android 手机 (Nexus 5X) 和 Mac (Quicktime) 上玩。没问题!正确的?!?但找到 Android 和 Python 之间匹配的编解码器/格式似乎并不简单。我想知道Android编写的文件/编解码器格式是否是非标准的并且FFMPEG无法读取它。
如果是这样,什么是好的音频格式/编解码器,可以在 Android 中简单编写并在 Python (2.7.x) 中读入数组。谢谢。

详细信息: 以下是 Android 代码的缩写形式:

private final int AUDIO_SAMPLE_RATE = 16000;   
private final String FILE_EXTENSION = "m4a";  // Audio file extension
mAbsolutePathFile = workingDir + "/" + mFilename + FILE_EXTENSION;
mMediaRecording = new MediaRecorder();
mMediaRecording.setAudioSource (MediaRecorder.AudioSource.MIC);
mMediaRecording.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecording.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecording.setAudioSamplingRate(AUDIO_SAMPLE_RATE);
mMediaRecording.setOutputFile(mAbsolutePathFile);
mMediaRecording.prepare();
mMediaRecording.start();

正如我所提到的,结果音频在 Android 和 MacOS 中都播放得很好,所以一切看起来都很好。我做了一些搜索来找到 AAC 音频的 python 包,并且 pydub 看起来是最简单的(我尝试了 audiotools,但找不到示例代码)。为了安装 pydub,我遵循了 instructions :

pip install pydub

brew install libav --with-libvorbis --with-sdl --with-theora

brew install ffmpeg --with-libvorbis --with-ffplay --with-theora

根据讨论 ( here ),我测试了 ffmpeg 并且它确实从命令行执行:

  $ffmpeg
  ffmpeg version 3.2.2 Copyright (c) 2000-2016 the FFmpeg developers
  built with Apple LLVM version 8.0.0 (clang-800.0.42.1)

但是当我尝试使用 Python 读取文件时:

import pydub
pydub.AudioSegment.from_file("sensorlog_2017-02-03_12-50-25-345_Dev26c5_Loc27_TypeAUDIO.m4a", "aac")

我得到:

Traceback (most recent call last):
  File "...anaconda2/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2881, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-8-607e3f2a62c3>", line 1, in <module>
pydub.AudioSegment.from_file("sensorlog_2017-02-03_12-50-25-345_Dev26c5_Loc27_TypeAUDIO.m4a", "aac")
File ".../anaconda2/lib/python2.7/site-packages/pydub/audio_segment.py", line 472, in from_file
    raise CouldntDecodeError("Decoding failed. ffmpeg returned error code: {0}\n\nOutput from ffmpeg/avlib:\n\n{1}".format(p.returncode, p_err))
CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1
Output from ffmpeg/avlib:
avconv version 11.4, Copyright (c) 2000-2014 the Libav developers
  built on Feb  3 2017 12:09:15 with Apple LLVM version 8.0.0 (clang-800.0.42.1)
[aac @ 0x7ff30001cc00] get_buffer() failed
[aac @ 0x7ff30001cc00] channel element 3.14 is not allocated
[aac @ 0x7ff30001cc00] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 0x7ff30001cc00] Input buffer exhausted before END element found
[aac @ 0x7ff30001cc00] More than one AAC RDB per ADTS frame is not implemented. Update your Libav version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[aac @ 0x7ff30001cc00] Error decoding AAC frame header.
[aac @ 0x7ff300001000] Could not find codec parameters (Audio: aac, 4.0, fltp, 213 kb/s)
[aac @ 0x7ff300001000] Estimating duration from bitrate, this may be inaccurate
/var/folders/cm/1r6x6rbj7hn_51qvfjzj7nx80000gn/T/tmps7b8Gf: could not find codec parameters

综上所述,这是Android和FFMPEG之间的冲突吗?我应该使用不同的编解码器/格式吗?我应该使用不同的 Python 音频库吗? 谢谢。

最佳答案

pydub 的 GitHub issues 中有一些额外的讨论,但对于 future 的流浪者,我相信解决方案是使用“mp4”作为格式

from pydub import AudioSegment
sound = AudioSegment.from_file("./sensorlog.m4a", format="mp4")

旁注:如果您无法找出正确的格式,您可以完全省略格式参数,pydub/ffmpeg/avconv/whoever 将尝试找出它。

sound = AudioSegment.from_file("./sensorlog.m4a")

您可能还会发现尝试 pydub.utils.mediainfo() 很有用,尽管根据您的 ffmpeg/avconv 安装,它可能可用也可能不可用(它在内部使用 ffprobe)

>>> from pydub.utils import mediainfo

>>> mediainfo("./sensorlog.m4a")

{u'DISPOSITION': {u'attached_pic': u'0',
  u'clean_effects': u'0',
  u'comment': u'0',
  u'default': u'1',
  u'dub': u'0',
  u'forced': u'0',
  u'hearing_impaired': u'0',
  u'karaoke': u'0',
  u'lyrics': u'0',
  u'original': u'0',
  u'timed_thumbnails': u'0',
  u'visual_impaired': u'0'},
 u'TAG': {u'com.android.version': u'7.0',
  u'compatible_brands': u'isommp42',
  u'creation_time': u'2017-02-03T20:50:33.000000Z',
  u'handler_name': u'SoundHandle',
  u'language': u'eng',
  u'major_brand': u'mp42',
  u'minor_version': u'0'},
 u'avg_frame_rate': u'0/0',
 u'bit_rate': u'15539',
 u'bits_per_raw_sample': u'N/A',
 u'bits_per_sample': u'0',
 u'channel_layout': u'mono',
 u'channels': u'1',
 u'codec_long_name': u'AAC (Advanced Audio Coding)',
 u'codec_name': u'aac',
 u'codec_tag': u'0x6134706d',
 u'codec_tag_string': u'mp4a',
 u'codec_time_base': u'1/8000',
 u'codec_type': u'audio',
 u'duration': u'7.808000',
 u'duration_ts': u'62464',
 u'filename': u'/Users/jiaaro/Downloads/sensorlog_2017-02-03_12-50-25-345_Dev26c5_Loc27_ActvAppTesting_TypeAUDIO.m4a',
 u'format_long_name': u'QuickTime / MOV',
 u'format_name': u'mov,mp4,m4a,3gp,3g2,mj2',
 u'id': u'N/A',
 u'index': u'0',
 u'max_bit_rate': u'12200',
 u'nb_frames': u'61',
 u'nb_programs': u'0',
 u'nb_read_frames': u'N/A',
 u'nb_read_packets': u'N/A',
 u'nb_streams': u'1',
 u'probe_score': u'100',
 u'profile': u'LC',
 u'r_frame_rate': u'0/0',
 u'sample_fmt': u'fltp',
 u'sample_rate': u'8000',
 u'size': u'15167',
 u'start_pts': u'0',
 u'start_time': u'0.000000',
 u'time_base': u'1/8000'}

关于Android:在Android中录制音频然后将音频读入python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42033701/

相关文章:

Android 模拟器版本 16.0 持久性/系统/存储?

python-2.7 - 如何使用 PySpark 并行运行独立转换?

java - 如何合并 MFCC

ios - MPMoviez PlayerViewController 只显示视频但不播放音频 iOS 8

audio - Unity3d-切换场景时不要重新加载audioSource

Android,在应用程序 WebView 中使用时,URL 是否存储在历史记录中?

java - 数据库文件上的 ENOENT(没有此类文件或目录)

android - 如何将 TestNG 与 Robolectric 一起使用?

python-2.7 - ipython/pylab/matplotlib安装初始化报错

python - 导入 scipy.special.expit 时出错