自定义长度拆分音频

173 阅读3分钟

欢迎来到我的博客!本博客旨在分享我的个人经验和见解,希望能够帮助到有兴趣的人。

现在,让我们开始吧!

  1. 引言

今天我想谈一谈如何使用ffmpeg自定义拆分MP3音频。ffmpeg下载安装以及配置环境变量暂且不表,使用ffmpeg是一项重要的技能,无论是在工作中还是生活中,都需要运用。因此,本文将提供一些实用的技巧和建议,帮助你自定义拆分音频(m4a,mp3,wav等格式音频)。

  1. 正文

首先,要训练一个声音模型,数据是必不可少的。通过python爬取在线听书的小说,最好是真人阅读的,有情感的抑扬顿挫,可以得到不同风格的声音,并巩固自己爬虫的技能。同时,多读也可以拓宽你的视野和思路,使你的创作力更加丰富和有趣。

其次,那么需要多长的音频呢?大概1-2h的资源最好,大概20章节真人阅读的小说。爬到的音频一般都是m4a格式的,你可以选择手动改成mp3后缀,或者使用ffmpeg修改。

ffmpeg -i 1.m4a -y -acodec libmp3lame -aq 0 1.mp3

除此之外,拿到的音频是不可以直接训练的,需要切片成5-15秒左右的音频,否则显卡跑不动会卡死;刚开始跟着UP主使用UER5切分,切了几个发现切的很慢,而且需要显卡才行,我用公司电脑没有显卡咋办?用ffmpeg就行了呀。

首先说明使用的依赖和导包


import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;

<!-- 编码,解码音频流文件 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>7</source>
        <target>7</target>
    </configuration>
</plugin>

a. 获取音频秒数的总长度


/**
 * 获取音频文件总时长
 *
 * @param file 文件
 * @return 转化后的总秒数
 */
public static long getTimeLen(File file) {
    long result = 0;
    if (file != null && file.exists()) {
        Encoder encoder = new Encoder();
        try {
            MultimediaInfo m = encoder.getInfo(file);
            long ls = m.getDuration();
            result = ls / 1000;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return result;
}

b. 按照时间等量切分,那一定需要一个数字转时间函数,因为ffmpeg的参数就是HH:MM:SS格式的

/**
 * 整数秒转换,精确到秒
 *
 * @param seconds 10
 * @return 00:00:10
 */
private static String secondToTime(int seconds) {
    if (seconds < 0) {
        throw new IllegalArgumentException("Seconds must be a positive number!");
    } else {
        int hour = seconds / 3600;
        int other = seconds % 3600;
        int minute = other / 60;
        int second = other % 60;
        StringBuilder sb = new StringBuilder();
        if (hour < 10) {
            sb.append("0");
        }
        sb.append(hour);
        sb.append(":");
        if (minute < 10) {
            sb.append("0");
        }
        sb.append(minute);
        sb.append(":");
        if (second < 10) {
            sb.append("0");
        }
        sb.append(second);
        return sb.toString();
    }
}

c. 一切就绪,开始切分

/**
 * 音频切割
 *
 * @param path     路径
 * @param fileName 文件名
 * @param timeLong 切割时长
 * @return 返回切割后文件列表
 */
public static List<String> wavToCutting(String path, String fileName, int timeLong) {
    Runtime run = null;
    List<String> result = new ArrayList<>();
    try {
        long start = System.currentTimeMillis();
        // 获取录音时长
        File file = new File(path + fileName);
        if (!file.exists()) {
            return null;
        }
        int audioLength = (int) getTimeLen(file);
        System.out.println("音频时长:" + audioLength);
        int startTime = 0;
        int endTime = 0;
        run = Runtime.getRuntime();
        while (endTime < audioLength) {
            endTime += timeLong;
            if (endTime > audioLength) {
                endTime = audioLength;
            }
            String cutFile = (path + fileName.replace(".mp3", "") + "_cut_" + startTime + "_" + endTime + ".mp3");
            String runCmd = "ffmpeg -i " + (path + fileName) + " -ss " + secondToTime(startTime) + " -to " + secondToTime(endTime) + " -y " + cutFile;
            Process p = run.exec(runCmd);

            System.out.println("执行:" + runCmd);
            result.add(cutFile);
            startTime = endTime;
        }
        long end = System.currentTimeMillis();
        System.out.println(" 分割耗时:" + (end - start) / 1000 + "秒");
        return result;
    } catch (Exception e) {
        System.out.println("异常:",e);
    } finally {
        if (null != run) {
            run.freeMemory();
        }
    }
    return result;
}

最后,得到5-15秒长度的音频,放到so-vits-svc训练模型。

1.png

  1. 结论

总之,提高切割音频需要付出一定的努力和耐心。通过爬虫,录音等方式,我们可以逐渐提高自己的解决问题的能力,并最终达到自己的目标。希望这些建议能够帮助到你,也欢迎你在评论区分享你的经验和技巧。

  1. 参考

以下是我参考的一些资料:

如果你想了解更多关于ffmpeg的信息,可以参考这些资料。同时,也欢迎你在评论区分享你喜欢的代码或者博客。