语音播报(播报本地音频文件)实现收款金额的播报

最近项目需要实现语音播报收款金额,本来要使用百度AL开发平台的语音合成进行语音播报,虽然这个是可以完美实现,但是这个在免费的情况下有这播放条数的限制,所以最终决定使用播放本地语音的方式进行实现。不多说,直接贴代码,代码也都进行了注释:

一、FileUtils文件读取工具类

public class FileUtils {

    public static AssetFileDescriptor getAssetFileDescription(String filename) throws IOException {
        AssetManager manager = CardDoctorApplication.getContext().getAssets();
        return manager.openFd(filename);
    }
}

CardDoctorApplication是自己的application类,就不贴出来了。

二、音频播放类

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 音频播放类
 * Created by Administrator on 2018/10/9.
 */

public class VoiceSpeaker {

    private static VoiceSpeaker sInstance;

    private ExecutorService service;//线程池

    private VoiceSpeaker() {
        service = Executors.newCachedThreadPool();
    }

    /**
     * 获取音频播放对象
     * @return
     */
    public static synchronized VoiceSpeaker getInstance() {
        if (sInstance == null) {
            sInstance = new VoiceSpeaker();
        }
        return sInstance;
    }


    /**
     * 播放前检查
     * @param list
     */
    public void speak(final List<String> list){
        if (service != null){
            service.execute(new Runnable() {
                @Override
                public void run() {
                    start(list);
                }
            });
        }
    }

    /**
     * 开始播放
     * @param list
     */
    private void start(final List<String> list) {
        synchronized (this) {
            final CountDownLatch latch = new CountDownLatch(1);//并发
            MediaPlayer player = new MediaPlayer();
            /**
             * 遍历音频模板集合,按顺序播放音频文件
             */
            if (list != null && list.size() > 0) {
                final int[] counter = {0};
                /**
                 * format方法使用占位符进行格式化
                 * %s中的 s 代表 字符串类型
                 *
                 * path是音频文件的路径,通过格式化之后匹配到对应的音频文件
                 */
                String path = String.format("sound/tts_%s.mp3", list.get(counter[0]));
                AssetFileDescriptor fd = null;
                try {
                    fd = FileUtils.getAssetFileDescription(path);
                    /**
                     * 设置要使用的数据源(FileDescriptor)。FileDescriptor必须是可搜索的(注意,LocalSocket不可搜索)。调用者有责任关闭文件描述符。
                     * 参数说明:
                     * 第一个参数:FileDescriptor:您要播放的文件的FileDescriptor
                     * 第二个参数:long:要播放的数据开始的文件的偏移量,以字节为单位
                     * 第三个参数:long:要播放的数据的字节长度
                     */
                    player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(),
                            fd.getLength());
                    /**
                     * 准备播放器以异步方式播放。设置数据源和显示表面后,您需要调用prepare()或prepareAsync()。
                     * 对于流,您应该调用prepareAsync(),它会立即返回,而不是阻塞,直到缓冲了足够的数据。
                     */
                    player.prepareAsync();
                    /**
                     * 注册媒体源准备播放时要调用的回调。
                     */
                    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            mp.start();
                        }
                    });
                    /**
                     * 注册在回放期间到达媒体源末尾时要调用的回调。
                     */
                    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            /**
                             * 将MediaPlayer重置为未初始化状态。调用此方法后,您必须通过设置数据源并调用prepare()再次初始化它。
                             */
                            mp.reset();
                            counter[0]++;
                            if (counter[0] < list.size()) {
                                try {
                                    AssetFileDescriptor fileDescriptor = FileUtils.getAssetFileDescription(String.format("sound/tts_%s.mp3", list.get(counter[0])));
                                    mp.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
                                    mp.prepare();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    latch.countDown();//完成预期工作,发出完成信号...
                                }
                            } else {
                                /**
                                 * 是否MediaPlayer资源
                                 */
                                mp.release();
                                latch.countDown();//完成预期工作,发出完成信号...
                            }
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                    latch.countDown();//完成预期工作,发出完成信号...
                }finally {
                    if (fd != null){
                        try {
                            fd.close();//关闭文件操作
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            try {
                latch.await();////等待主线程执行完毕,获得开始执行信号...
                this.notifyAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

三、音频播放模板处理类

import android.text.TextUtils;

import com.yunkahui.datacubeper.common.utils.LogUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 音频播放模板处理类
 * Created by Administrator on 2018/10/9.
 */

public class VoiceTemplate {
    private static final String DOT = ".";

    private String numString;

    private String prefix;//收款成功音频

    private String suffix;//元的音频

    public VoiceTemplate() {

    }

    /**
     * 获取播放的音频文件顺序集合
     *
     * @param money
     * @return
     */
    public static List<String> getDefaultTemplate(String money) {
        return new VoiceTemplate()
                .prefix("success")
                .numString(money)
                .suffix("yuan")
                .gen();
    }

    public String getPrefix() {
        return prefix;
    }

    public VoiceTemplate prefix(String prefix) {
        this.prefix = prefix;
        return this;
    }

    public String getSuffix() {
        return suffix;
    }

    public VoiceTemplate suffix(String suffix) {
        this.suffix = suffix;
        return this;
    }


    public String getNumString() {
        return numString;
    }

    public VoiceTemplate numString(String numString) {
        this.numString = numString;
        return this;
    }


    public List<String> gen() {
        return genVoiceList();
    }

    private List<String> createReadableNumList(String numString) {
        List<String> result = new ArrayList<>();
        if (!TextUtils.isEmpty(numString)) {
            int len = numString.length();
            for (int i = 0; i < len; i++) {
                if ('.' == numString.charAt(i)) {
                    result.add("dot");
                } else {
                    result.add(String.valueOf(numString.charAt(i)));
                }
            }
        }
        return result;
    }


    /**
     * 播放音频文件顺序
     *
     * @return
     */
    private List<String> genVoiceList() {
        List<String> result = new ArrayList<>();
        if (!TextUtils.isEmpty(prefix)) {
            result.add(prefix);
        }
        if (!TextUtils.isEmpty(numString)) {
            result.addAll(genReadableMoney(numString));
        }

        if (!TextUtils.isEmpty(suffix)) {
            result.add(suffix);
        }
        return result;
    }

    /**
     * 拆分金额成一个集合,以对应音频文件
     *
     * @param numString
     * @return
     */
    private List<String> genReadableMoney(String numString) {
        List<String> result = new ArrayList<>();
        if (!TextUtils.isEmpty(numString)) {
            /**
             * contains()返回TRUE时,该字符串中存在该字符
             * 此处判断字符串是否包含小数点
             */
            if (numString.contains(DOT)) {
                String integerPart = numString.split("\\.")[0];
                String decimalPart = numString.split("\\.")[1];
                //整数部分
                List<String> intList = readIntPart(integerPart);
                //小数点之后的部分
                List<String> decimalList = readDecimalPart(decimalPart);
                result.addAll(intList);
                if (!decimalList.isEmpty()) {
                    result.add("dot");
                    result.addAll(decimalList);
                }
            } else {
                //int
                result.addAll(readIntPart(numString));
            }
        }
        return result;
    }

    /**
     * 拆分小数点后面字符串
     *
     * @param decimalPart
     * @return
     */
    private List<String> readDecimalPart(String decimalPart) {
        List<String> result = new ArrayList<>();
        if (!"00".equals(decimalPart)) {
            char[] chars = decimalPart.toCharArray();
            for (char ch : chars) {
                result.add(String.valueOf(ch));
            }
        }
        return result;
    }

    /**
     * 当金额为整数时,直接拆分,拆分成
     *
     * @param integerPart
     * @return
     */
    private List<String> readIntPart(String integerPart) {
        List<String> result = new ArrayList<>();
        String intString = readLong(Long.parseLong(integerPart));
        int len = intString.length();
        for (int i = 0; i < len; i++) {
            char current = intString.charAt(i);
            if (current == '拾') {
                result.add("ten");
            } else if (current == '佰') {
                result.add("hundred");
            } else if (current == '仟') {
                result.add("thousand");
            } else if (current == '万') {
                result.add("ten_thousand");
            } else if (current == '亿') {
                result.add("ten_million");
            } else {
                result.add(String.valueOf(current));
            }
        }
        return result;
    }


    private static final char[] NUM = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    private static final char[] CHINESE_UNIT = {'元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟'};

    /**
     * 返回关于钱的中文式大写数字,支仅持到亿,超过亿则需要使用长整型long
     */
    public static String readLong(long moneyNum) {
        long mMoneyNum = moneyNum;
        String res = "";
        int i = 0;
        if (moneyNum == 0) {
            return "0";
        }

        if (moneyNum == 10) {
            return "拾";
        }

        if (moneyNum > 10 && moneyNum < 20) {
            return "拾" + moneyNum % 10;
        }

        while (moneyNum > 0) {
            res = CHINESE_UNIT[i++] + res;
            res = NUM[(int) (moneyNum % 10)] + res;
            moneyNum /= 10;
        }
        /**
         * replaceAll() 方法使用给定的参数 replacement 替换字符串所有匹配给定的正则表达式的子字符串。
         * 参数
         * 第一个参数:regex -- 匹配此字符串的正则表达式。
         * 第二个参数:newChar -- 用来替换每个匹配项的字符串。
         * 成功则返回替换的字符串,失败则返回原始字符串。
         */
        if (mMoneyNum >= 100000000) {
            //整亿
            if (mMoneyNum % 100000000 == 0) {
                return res.replaceAll("0[拾佰仟万]", "0")
                        .replaceAll("0+亿", "亿").replaceAll("0+万", "万")
                        .replaceAll("0+元", "元").replaceAll("0+", "0")
                        .replace("元", "");
            } else {
                //非整亿,有万位或者千位(这里万位包括万、十万、百万、千万位)
                String a = String.valueOf(mMoneyNum);
                LogUtils.e("原始数据--》" + a);
                LogUtils.e("截取万位--》" + a.substring(a.length() - 8, a.length() - 4));
                if (Long.parseLong(String.valueOf(mMoneyNum).substring(String.valueOf(mMoneyNum).length() - 8, String.valueOf(mMoneyNum).length() - 4)) == 0) {
                    //万位为全部为0的情况,例如 1500002000.00 此情况不需要读出 万,直接读一十五亿零二千元
                    return res.replaceAll("0[拾佰仟]", "0")
                            .replaceAll("0+亿", "亿").replaceAll("0+万", "0")
                            .replaceAll("0+元", "元").replaceAll("0+", "0")
                            .replace("元", "");

                } else {
                    //万位为不为0的情况,例如  1520002000.00 此情况需要读出 万,读一十五亿二千万二千元
                    return res.replaceAll("0[拾佰仟]", "0")
                            .replaceAll("0+亿", "亿").replaceAll("0+万", "万")
                            .replaceAll("0+元", "元").replaceAll("0+", "0")
                            .replace("元", "");
                }
            }
        } else {
            //小于一亿
            return res.replaceAll("0[拾佰仟]", "0")
                    .replaceAll("0+亿", "亿").replaceAll("0+万", "万")
                    .replaceAll("0+元", "元").replaceAll("0+", "0")
                    .replace("元", "");
        }
    }

}

四、新建assets文件夹,把音频文件放在assets目录下

此demo可支持到千亿播放,对播放的语序也进行了一些处理,但是可能还有些许情况没有考虑到,需要使用的朋友可以按自己的需求自行添加

新添加内容:

最近接到反馈,说语音播报的速度太慢,跟一个老大爷一样,所以在处方面做了优化。此处没有使用Android自带的播放器,而是使用Google支持的第三方的播放器ExoPlayer ,需要了解ExoPlayer 可到这个网址了解,https://google.github.io/ExoPlayer/

ExoPlayer gitgub地址https://github.com/google/ExoPlayer

扫描二维码关注公众号,回复: 5687598 查看本文章

下面直接贴出代码,新的代码只是一个方法,替换之前的播报方法即可,或者根据需求使用两者中的其中一个即可。

private ConcatenatingMediaSource mConcatenatingMediaSource;

private List<MediaSource> mMediaSourceList;
private void exoPlayerStart(final List<String> list) {
    synchronized (this){
        if (mMediaSourceList == null) {
            mMediaSourceList = new ArrayList<>();
        }
        mMediaSourceList.clear();
        final CountDownLatch latch = new CountDownLatch(1);//并发
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(CardDoctorApplication.getInstance().getContext(),
                Util.getUserAgent(CardDoctorApplication.getInstance().getContext(), "CardDoctor"));
        final SimpleExoPlayer mPlayer = ExoPlayerFactory.newSimpleInstance(CardDoctorApplication.getInstance().getContext());
        for (int i = 0; i < list.size(); i++) {
            MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(FileUtils.getAssetsPath(String.format("sound/tts_%s.mp3", list.get(i)))));
            mMediaSourceList.add(mediaSource);
        }

        switch (mMediaSourceList.size()) {
            case 1:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0));
                break;
            case 2:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1));
                break;
            case 3:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2));
                break;
            case 4:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3));
                break;
            case 5:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4));
                break;
            case 6:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5));
                break;
            case 7:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6));
                break;
            case 8:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7));
                break;
            case 9:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8));
                break;
            case 10:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9));
                break;
            case 11:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10));
                break;
            case 12:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11));
                break;
            case 13:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12));
                break;
            case 14:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13));
                break;
            case 15:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14));
                break;
            case 16:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15));
                break;
            case 17:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16));
                break;
            case 18:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17));
                break;
            case 19:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18));
                break;
            case 20:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19));
                break;
            case 21:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19),mMediaSourceList.get(20));
                break;
            case 22:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19), mMediaSourceList.get(20),mMediaSourceList.get(21));
                break;
            case 23:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19), mMediaSourceList.get(20), mMediaSourceList.get(21),
                        mMediaSourceList.get(22));
                break;
            case 24:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19),mMediaSourceList.get(20), mMediaSourceList.get(21),
                        mMediaSourceList.get(22), mMediaSourceList.get(23));
                break;
            case 25:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19),mMediaSourceList.get(20), mMediaSourceList.get(21),
                        mMediaSourceList.get(22), mMediaSourceList.get(23),mMediaSourceList.get(24));
                break;
            case 26:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19),mMediaSourceList.get(20), mMediaSourceList.get(21),
                        mMediaSourceList.get(22), mMediaSourceList.get(23),mMediaSourceList.get(24),mMediaSourceList.get(25));
                break;
            case 27:
                mConcatenatingMediaSource = new ConcatenatingMediaSource(mMediaSourceList.get(0), mMediaSourceList.get(1), mMediaSourceList.get(2), mMediaSourceList.get(3),
                        mMediaSourceList.get(4), mMediaSourceList.get(5), mMediaSourceList.get(6), mMediaSourceList.get(7), mMediaSourceList.get(8), mMediaSourceList.get(9),
                        mMediaSourceList.get(10), mMediaSourceList.get(11), mMediaSourceList.get(12), mMediaSourceList.get(13), mMediaSourceList.get(14), mMediaSourceList.get(15),
                        mMediaSourceList.get(16), mMediaSourceList.get(17), mMediaSourceList.get(18), mMediaSourceList.get(19),mMediaSourceList.get(20), mMediaSourceList.get(21),
                        mMediaSourceList.get(22), mMediaSourceList.get(23),mMediaSourceList.get(24),mMediaSourceList.get(25),mMediaSourceList.get(26));
                break;
            default:
                break;
        }


        mPlayer.addListener(new Player.EventListener() {
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                if (playbackState == 4) {
                    mPlayer.release();
                    latch.countDown();
                }
            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                mPlayer.release();
                latch.countDown();
            }
        });


        mPlayer.prepare(mConcatenatingMediaSource);
        mPlayer.setPlayWhenReady(true);

        try {
            latch.await();
            this.notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

最后附上播放的音频文件与以上代码https://download.csdn.net/download/freak_csh/10786233

github 项目https://github.com/freakcsh/VoiceDemo.git 此项目还接入了百度语音的demo,还有极光推送,但是极光被我干掉了,使用不了。

猜你喜欢

转载自blog.csdn.net/freak_csh/article/details/84101054