【Audio】Unity音频模块:加载、转换、剪切、混音、合并

GitHub项目:Epitome.Audio音频模块

WWW类外部加载音乐文件

使用delegate委托:音频加载完成进行回调

namespace Epitome
{
    public delegate void AudioClipLoadFinish(AudioClip clip);

    public static class AudioLoad
    {
        public static IEnumerator Load(string url, AudioClipLoadFinish finish)
        {
            WWW www = new WWW("file://" + url);
            yield return www;
            finish(www.GetAudioClip());
        }
    }
}

使用案列:

public AudioSource accompany;

private void Start()
{
	// 加载音频
	StartCoroutine(AudioLoad.Load("filepath", AudioClipLoadFinish));
}
    
public void AudioClipLoadFinish(AudioClip clip)
{
	accompany.clip = clip;
	accompany.Paly();
}

NAudio介绍

NAudio是Mark Heath编写的开源.NET音频库
GitHub:NAudio项目
NAudio是个相对成熟、开源的C#音频开发工具,它包含录音、播放录音、格式转换、混音调整等功能。

基于NAudio音频文件格式转换

namespace Epitome
{
    public static class AudioConverter
    {
        /// <summary>
        /// MP3文件转WAV文件
        /// </summary>
        /// <param name="filePath">MP3文件读取路径</param>
        /// <param name="savePath">WAV文件保存路径</param>
        public static void MP3TurnWAV(string filePath, string savePath)
        {
            using (FileStream stream = File.Open(filePath, FileMode.Open))
            {
                Mp3FileReader reader = new Mp3FileReader(stream);
                WaveFileWriter.CreateWaveFile(savePath, reader);
            }
        }

        public static void MP3TurnWAV(string filePath, string savePath, List<string> fileNames)
        {
            List<string> strs = Project.DirectoryAllFileNames(filePath, new List<string>() { "mp3" });

            if (strs != null)
            {
                string targetFilePath, saveFilePath;
                for (int j = 0; j < strs.Count; j++)
                {
                    targetFilePath = filePath + "/" + strs[j];
                    saveFilePath = savePath + "/" + strs[j].Substring(0, strs[j].Length - 3) + "wav";
                    MP3TurnWAV(targetFilePath, saveFilePath);
                }
#if UNITY_EDITOR
                AssetDatabase.Refresh();
#endif
            }
        }
	}
}

使用案列:
EditorExtension.GetSelectionPath:获取编辑器选择的目标路径,获取该路径下的MP3音频文件
通过拼接音频文件路径,调用MP3TurnWAV生成WAV音频文件

/// <summary>
/// MP3文件转WAV文件
/// </summary>
[MenuItem("Epitome/Audio/MP3TurnWAV")]
[MenuItem("Assets/Epitome/Audio/MP3TurnWAV")]
private static void MP3TurnWAV()
{
    List<string> paths = EditorExtension.GetSelectionPath();
    for (int i = 0; i < paths.Count; i++)
    {
        if (Directory.Exists(paths[i]))
        {
            string rootPath = ProjectPath.GetDataPath.Substring(0, ProjectPath.GetDataPath.Length - 6);

            DirectoryInfo info = new DirectoryInfo(rootPath + paths[i]);

            string savePath = info.FullName + "_WAV";

            Project.CreateDirectory(savePath);

            List<string> strs = Project.DirectoryAllFileNames(info.FullName, new List<string>() { "mp3" });

            AudioConverter.MP3TurnWAV(info.FullName, savePath, strs);
        }
    }
}

音频剪切

/// <summary>
/// 剪切空白部分
/// </summary>
public static AudioClip CutBlankSection(AudioClip audioClip, int time, int samplingRate)
{
    float[] samples_one = new float[audioClip.samples];

    audioClip.GetData(samples_one, 0);

    float[] samples_two = new float[time * samplingRate];

    Array.Copy(samples_one, 0, samples_two, 0, time * samplingRate);

    AudioClip newAudioClip = AudioClip.Create(audioClip.name, samplingRate * time, 1, samplingRate, false);
    newAudioClip.SetData(samples_two, 0);

    return newAudioClip;
}

audioLength//秒单位
frequency = 44100;
AudioClip audioClip = AudioClips.CutBlankSection(recording.clip, audioLength, frequency);

基于NAudio音频剪切

/// <summary>
/// 修剪Wav文件
/// </summary>
/// <param name="filePath">修剪文件路径</param>
/// <param name="savePath">保存文件路径</param>
/// <param name="cutFromStart">开始间隔</param>
/// <param name="cutFromEnd">结束间隔</param>
public static void TrimWavFile(string filePath, string savePath, TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
    using (WaveFileReader reader = new WaveFileReader(filePath))
    {
        using (WaveFileWriter writer = new WaveFileWriter(savePath, reader.WaveFormat))
        {
            int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000;

            int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond;
            startPos = startPos - startPos % reader.WaveFormat.BlockAlign;

            int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond;
            endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
            int endPos = (int)reader.Length - endBytes;

            TrimWavFile(reader, writer, startPos, endPos);
        }
    }
}

/// <summary>
/// 修剪Wav文件
/// </summary>
private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos)
{
    reader.Position = startPos;
    byte[] buffer = new byte[1024];
    while (reader.Position < endPos)
    {
        int bytesRequired = (int)(endPos - reader.Position);
        if (bytesRequired > 0)
        {
            int bytesToRead = Math.Min(bytesRequired, buffer.Length);
            int bytesRead = reader.Read(buffer, 0, bytesToRead);
            if (bytesRead > 0)
            {
                writer.Write(buffer, 0, bytesRead);
            }
        }
    }
}

基于NAudio音频混合(混音)

namespace Epitome
{
    public static class AudioMixer
    {
        /// <summary>
        /// 音频混合(混音)
        /// </summary>
        /// <param name="filePath1">音频文件路径</param>
        /// <param name="filePath2">音频文件路径</param>
        /// <param name="mixedPath">混合音频文件路径</param>
        public static void AudioMixing(string filePath1, string filePath2,string mixedPath)
        {
            using (var reader1 = new AudioFileReader(filePath1))
            using (var reader2 = new AudioFileReader(filePath2))
            {
                var mixer = new MixingSampleProvider(new[] { reader1, reader2 });
                WaveFileWriter.CreateWaveFile16(mixedPath, mixer);
            }
        }
    }
}

使用案列:

// 伴奏混合原声
AudioMixer.AudioMixing(accompanyClipPath, originalPath, finalPath);

音频合并

/// <summary>
/// 合并音频
/// </summary>
public static AudioClip MergeAudio(int interval, params AudioClip[] clips)
{
    if (clips == null || clips.Length == 0)
        return null;

    int channels = clips[0].channels;
    int frequency = clips[0].frequency;

    using (MemoryStream memoryStream = new MemoryStream())
    {
        for (int i = 0; i < clips.Length; i++)
        {
            if (clips[i] == null)
                continue;

            clips[i].LoadAudioData();

            var buffer = clips[i].GetData();

            memoryStream.Write(buffer, 0, buffer.Length);

            if (clips.Length - 1 == i)
                continue;

            byte[] byteClips = new byte[clips[i].frequency * clips[i].channels * 4 * interval];//合并音频间的间隔
            memoryStream.Write(byteClips, 0, byteClips.Length);
        }

        var bytes = memoryStream.ToArray();

        var result = AudioClip.Create("Merge", bytes.Length / 4 / channels, channels, 44100, false);

        result.SetData(bytes);

        return result;
    }
}
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity加载音频文件可以使用 `AudioClip` 类。以下是一种常见的加载音频文件的方法: 1. 将音频文件放置在 Unity 项目的 `Assets` 文件夹中,或者在代码中指定音频文件的路径。 2. 使用 `AudioClip` 类的 `LoadAudioData` 方法加载音频文件。可以使用 `Resources.Load` 方法或 `AudioClip.CreateFromFile` 方法来加载音频文件。 以下是一个示例代码,用于在 Unity加载音频文件: ```csharp using UnityEngine; public class AudioManager : MonoBehaviour { public AudioClip audioClip; // 音频文件 private AudioSource audioSource; void Start() { audioSource = GetComponent<AudioSource>(); // 通过 Resources.Load 方法加载音频文件 // audioClip = Resources.Load<AudioClip>("Audio/your_audio_file"); // 或者通过 AudioClip.CreateFromFile 方法加载音频文件 // audioClip = AudioClip.CreateFromFile("path_to_your_audio_file.wav"); // 加载完成后,将音频文件赋值给 AudioSource 组件 audioSource.clip = audioClip; // 播放音频 audioSource.Play(); } } ``` 在上面的代码中,你可以使用 `Resources.Load<AudioClip>` 方法按照资源路径加载音频文件,并将其赋值给 `audioClip` 变量。或者你也可以使用 `AudioClip.CreateFromFile` 方法通过文件路径加载音频文件。 然后,将加载音频文件赋值给 `AudioSource` 组件的 `clip` 属性,并调用 `Play` 方法播放音频。 请确保在代码中将 `AudioManager` 脚本附加到具有 `AudioSource` 组件的游戏对象上,以便能够播放加载音频文件。 这是一种基本的音频加载方法,你可以根据具体需求进行进一步的自定义和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JIQIU.YANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值