Mp3 文件音频转换成微信语音 Silk 下篇

3,220 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

Mp3 文件音频转换成微信语音 Silk 下篇

人,就像钉子一样,一旦失去了方向,开始向阻力屈身,那么就失去了他们存在的价值——兰道

silk-v3-decoder 安装

上传安装包

image.png

解压

    这个是zip包所以我们的linux系统需要unzip指令支持,所以我们要安装一下unzip工具

sudo yum install unzip

image.png
    解压上传的zip包

unzip silk-v3-decoder-master.zip

image.png
image.png

手动编译

    进入到对应的文件目录下进行软件的编译操作,下面的路径是我本地的路径看你们自己的文件路径进行更改

cd /usr/local/software/silk-v3-decoder-master/silk

编译

make encoder

image.png
    编译完就会出现这种一个 encoder 可执行的指令

测试是否安装成功

    测试该插件是否能安装成功的标志就是是否能进行将pcm文件转换成silk文件

# 指令转换语法
encoder {源文件} {目标文件} -tencent

真实文件测试

/usr/local/software/silk-v3-decoder-master/silk/encoder 格式转换测试.pcm 格式转换测试.silk -tencent

测试结果

image.png
image.png
    到这里我们就已经成功的将其安装成功了,并且已经将mp3的音频格式转换成了silk的微信语音格式了

指令测试

第一步通过 ffmpeg

    ffmpeg 将MP3 文件转换成 pcm 文件

第二部通过第三方插件

    silk-v3-decoder 将pcm 转换成 silk文件

java 代码实现

MP3 文件下载

/**
* 下载MP3 文件
*
* @param pushRequestDTO 请求实体
* @param mp3SourceFile  本地 mp3 名字
*/
private String downLoadMp3(PushVoiceDTO pushRequestDTO, String mp3SourceFile) {
    String voiceUrl = pushRequestDTO.getVoiceUrl();
    FileOutputStream fileOutputStream = null;
    ReadableByteChannel channel = null;
    try {
        URL url = new URL(voiceUrl);
        channel = Channels.newChannel(url.openStream());
        fileOutputStream = new FileOutputStream(FILE_SAVE_ADDR + mp3SourceFile);
        fileOutputStream.getChannel().transferFrom(channel, 0, Long.MAX_VALUE);
        logger.info("MP3 文件名字 : {} 下载成功", mp3SourceFile);
        return FILE_SAVE_ADDR + mp3SourceFile;
    } catch (IOException e) {
        e.printStackTrace();
        return "";
    } finally {
        try {
            // 有可能出现文件找不到的情况,所以此时有可能出现此处文件输出流为空的情况
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
            // 此时也有可能出现此处文件的channel通道为空的情况
            if (channel != null) {
                channel.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MP3 转化成 PCM

/**
     * 进行MP3格式向pcm格式转换
     *
     * @param filePrefix    文件前缀
     * @param mp3SourceFile mp3 源文件
     * @return
     */
private String mp3ToPcm(String filePrefix, String mp3SourceFile, File mp3File) {
    String pcmTargetFile = FILE_SAVE_ADDR + filePrefix + PCM_VOICE_SUFFIX;
    String mp3SourceFileAddr = FILE_SAVE_ADDR + mp3SourceFile;
    String command = StringUtils.replaceEach(MP3_TO_PCM_COMMAND, COMMAND_FORMAT, 
                new String[]{mp3SourceFileAddr, pcmTargetFile});
    try {
        logger.info("MP3文件 转 PCM文件 命令为 :{}", command);
        Process mp3Exec = Runtime.getRuntime().exec(command);
        mp3Exec.waitFor();
        logger.info("MP3 转 PCM 文件成功");
        // 当执行完MP3转PCM之后需要将MP3原文件删除
        boolean mp3DeleteFlag = mp3File.delete();
        if (mp3DeleteFlag) {
            logger.info("MP3 文件删除成功");
        }
        return pcmTargetFile;
    } catch (Exception e) {
        e.printStackTrace();
        logger.info("MP3 转 PCM 文件失败");
    }
    return "";
}

获取MP3 音频时长

/**
     * 获取音频时间
     *
     * @param pushRequestDTO 请求体
     * @param mp3File        mp3 文件
     * @throws IOException
     * @throws TagException
     * @throws ReadOnlyFileException
     * @throws InvalidAudioFrameException
     */

private Integer getVoiceTime(PushVoiceDTO pushRequestDTO, File mp3File) {
    // 如果MP3文件存在那么就获取当前MP3的播放时长
    MP3FileReader mp3FileReader = new MP3FileReader();
    AudioFile audioFile = null;
    try {
        audioFile = mp3FileReader.read(mp3File);
    } catch (Exception e) {
        e.printStackTrace();
    }
    // 如果mp3文件不为空
    if (Objects.nonNull(audioFile)) {
        // 获取MP3文件的头部信息
        AudioHeader audioHeader = audioFile.getAudioHeader();
        // 返回MP3文件时长
        return audioHeader.getTrackLength();
    }
    return 0;
}

PCM 转化成 SILK

/**
     * 进行pcm向silk格式转换
     *
     * @param pcmTargetFileName  pcm 目标源文件
     * @param silkTargetFileName silk 目标文件
     */
private String pcmToSilk(String pcmTargetFileName, String silkTargetFileName, File filePcm) {
    // 创建PCM转SILK的指令
    String pcmTargetFile = FILE_SAVE_ADDR + pcmTargetFileName;
    String silkSourceFile = FILE_SAVE_ADDR + silkTargetFileName;
    String pcmToSilkCommand = PCM_TO_SILK_COMMAND + COMMAND_SPACE + pcmTargetFile + COMMAND_SPACE + 
                    silkSourceFile + COMMAND_SPACE + PCM_TO_SILK_COMMAND_SUFFIX;
    try {
        logger.info("PCM 文件转 SILK 文件命令为 :{}", pcmToSilkCommand);
        Process pcmToSilkExec = Runtime.getRuntime().exec(pcmToSilkCommand);
        pcmToSilkExec.waitFor();
        logger.info("PCM 转 SILK 文件成功");
        boolean pcmDeleteFlag = filePcm.delete();
        if (pcmDeleteFlag) {
            logger.info("PCM 文件删除成功");
        }
        return silkSourceFile;
    } catch (Exception e) {
        logger.error("PCM 转 SILK 文件出现异常 , MESSAGE: {} ,CAUSE: ", e.getMessage(), e.getCause());
        logger.info("PCM 转 SILK 文件失败");
    }
    return "";
}

总结

    到这里我们就成功的将MP3文件转换成了SILK文件