将 MP3 转成 PCM 并使用 AudioTrack 播放

环境

Android Studio Bumblebee, Mac mini 2014

问题描述

需要实现功能为:将 MP3 转成 PCM 并通过 UDP 传出去。

任务可分解为:

  1. 将 MP3 转成 PCM
  2. 将 PCM 通过 AudioTrack 播放以确保转换的 PCM 文件正常
  3. 将 PCM 通过 UDP 传出去。

问题分析

注:写文章引用来源一直力求引用原创,但下面很多引文没找到原创文献

1 将 MP3 转成 PCM

面向搜索引擎编程,Java 直接有转换用的 API: AudioSystem。转换方式参照 CSDN 博文

这里有点要说明,如果直接使用,会提示找不到 javax.sound.sampled.AudioSystem, 原因是 Android 自带的包覆盖掉了 JRE 里面的文件。

解决方法是将 JRE 中包添加到 Android 醒目的 ‘build.gradle’ 的依赖里面。-- 此处博文忘记引文地址了。

implementation files('/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/rt.jar')

问题是,我使用AudioSystem.write() 转换数据,总是提示 could not write audio file: file type not supported, 问题可能是 输出文件的 AudioFomat 设置有问题,但尝试了许久,没找到问题点。

不能总吊在一棵树上。此计不通,立马考虑其他方法。直接在外面将 MP3 转成 PCM。在网站即时工具箱 中将 MP3 转成 PCM. 该页面有很简单的转换设置项。转换后出来的文件,使用 AudioTrack 播放,出来的是滋滋滋的声音,网上是说可能是大小端的问题。但网页转换没有这个设置项,没法验证。办法二宣告失败。

网上另一种途径是使用 FFMPEG 将 MP3 转换成 PCM。把我树莓派搬出来。参考博文mp3文件转pcm文件,生成了 单通道-8k采样率 的 PCM 文件。但使用 ffplay 播放时报错 ‘could not initialize sdl - displayindex must be in the range 0 - -1。首先安装 SDL。安装完成后,播放 PCM 仍旧有相同报错。貌似调试 SDL 也得大费周章。

2 使用 AudioTrack 播放以验证 PCM 正常

鉴于调试 SDL 也是不小的工程,遂停止使用 SDL 播放的尝试,直接在 Android 里面使用 AudioTrack 播放,正常,谢天谢地。

AudioTrack udioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_DEFAULT,
 AudioFormat.ENCODING_PCM_16BIT, 15000, AudioTrack.MODE_STREAM);
 
 binding.play.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        pcmAudioTrack.play();

                        InputStream inputStream = null;
                        byte[] data = new byte[5000];
                        AssetManager assetManager = getAssets();
                        try {
                            inputStream = assetManager.open("dujia.pcm");
                            int length = 0;
                            while((length = inputStream.read(data))!= -1) {
                                pcmAudioTrack.write(data, 0, length);
                                SystemClock.sleep(100);
                            }
                            pcmAudioTrack.stop();
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
    });

3 将 PCM 通过 UDP 传出去

这里是与上一步类似,将 PCM 文件以流的方式读入并按照接收端定义的格式打包后通过 UDP 传出去。具体过程非重点,略过不表。

这里要强调两点:

public static ArrayList<String> getConnectedIP() {
 ArrayList<String> connectedIP = new ArrayList<>();
    try {
        BufferedReader bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"));
        String line = bufferedReader.readLine();
        while ((line = bufferedReader.readLine()) != null) {
            String[] splitted = line.split(" +");
            if (splitted.length >= 4) {
                String ip = splitted[0];
                connectedIP.add(ip);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return connectedIP;
}

需要注意两点:一是在 Android 10 及以上手机中可能提示没有权限,换低版本系统手机即可。二是在 Android Studio 终端 或者 Mac 终端 使用同样命令获取到设备IP:

adb shell
cat /proc/net/arp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、Java实现wav音频文件换为pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件(PCMPlay.java) WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。 PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。 简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。 WAV和PCM的关系 WAV可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互换之中,例如MP3换成WMA。 简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值