一种MP3文件的压缩方法

事情是这样的

有一批音频需要压缩。这些音频主要是课文朗读。因为不是歌曲,质量要求不高,所以使用了比较低的质量,对于有些音频能压制到原来的八分之一的体积例如 (大小为78M的音频 压缩到9M)。

  MP3FileProcessor.CompressAndResampleMp3(fn_old, fn);

默认使用下面的压制参数 

采样率  int targetSampleRate= 8000

比特率 int bitRate=32

声道数 int channels=1

重采样质量  ResamplerQuality = 60


            if (!File.Exists(inputFilePath))
                throw new FileNotFoundException("输入文件不存在", inputFilePath);

            if (string.IsNullOrEmpty(outputFilePath))
                throw new ArgumentException("输出文件路径不能为空");

            if (channels != 1 && channels != 2)
                throw new ArgumentException("声道数必须为1(单声道)或2(立体声)", nameof(channels));

            // 支持的采样率验证(常见MP3采样率)
            int[] supportedSampleRates = { 8000, 11025, 16000, 22050, 32000, 44100, 48000 };
            if (Array.IndexOf(supportedSampleRates, targetSampleRate) == -1)
                throw new ArgumentException("不支持的采样率", nameof(targetSampleRate));

            // 支持的比特率验证(LAME支持的常见比特率)
            if (bitRate < 32 || bitRate > 320 || bitRate % 8 != 0)
                throw new ArgumentException("无效的比特率,必须是32-320之间的8的倍数", nameof(bitRate));

            // 确保输出目录存在
            var outputDir = Path.GetDirectoryName(outputFilePath);
            if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
                Directory.CreateDirectory(outputDir);

            WaveStream reader = null;
            WaveStream resampledStream = null;
            LameMP3FileWriter writer = null;

            try
            {
                // 读取输入音频文件(NAudio会自动识别格式)
                reader = new AudioFileReader(inputFilePath);

                // 如果需要重采样或改变声道数
                if (reader.WaveFormat.SampleRate != targetSampleRate ||
                    reader.WaveFormat.Channels != channels)
                {
                    // 创建重采样器
                    var resampler = new MediaFoundationResampler(reader,
                        WaveFormat.CreateIeeeFloatWaveFormat(targetSampleRate, channels));

                    // 重采样质量设置(0-100,越高质量越好但速度越慢)
                    resampler.ResamplerQuality = 60;
                    resampledStream = new WaveProviderToStreamAdapter(resampler);
                }
                else
                {
                    // 无需重采样,直接使用原始流
                    resampledStream = reader;
                }

                // 初始化LAME编码器设置
                LameConfig lameConfig = new LameConfig();
                lameConfig.BitRate = bitRate;

                // 创建MP3写入器(内部会初始化LAME编码器)
                writer = new LameMP3FileWriter(outputFilePath,
                    resampledStream.WaveFormat,
                    lameConfig);

                // 缓冲区大小(根据采样率调整,确保处理效率)
                var bufferSize = resampledStream.WaveFormat.AverageBytesPerSecond / 4;
                var buffer = new byte[bufferSize];
                int bytesRead;

                // 处理音频数据
                while ((bytesRead = resampledStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    writer.Write(buffer, 0, bytesRead);
                }
            }
            catch (Exception ex)
            {
                // 清理可能生成的不完整文件
                if (File.Exists(outputFilePath))
                    File.Delete(outputFilePath);

                throw new IOException("MP3处理失败", ex);
            }
            finally
            {
                // 确保资源释放
                writer?.Dispose();
                resampledStream?.Dispose();
                reader?.Dispose();
            }

代码

    public class MP3FileProcessor
    {

        public class WaveProviderToStreamAdapter : WaveStream
        {
            private readonly IWaveProvider _provider;
            private long _position;

            public WaveProviderToStreamAdapter(IWaveProvider provider)
            {
                _provider = provider ?? throw new ArgumentNullException(nameof(provider));
            }

            public override WaveFormat WaveFormat => _provider.WaveFormat;

            // 对于实时生成的流(如重采样器),长度无法预知,返回long.MaxValue
            public override long Length => long.MaxValue;

            public override long Position
            {
                get => _position;
                set => _position = value; // 重采样流不支持定位,此处仅作占位
            }

            public override int Read(byte[] buffer, int offset, int count)
            {
                int bytesRead = _provider.Read(buffer, offset, count);
                _position += bytesRead;
                return bytesRead;
            }
        }
        public static void CompressAndResampleMp3(string inputFilePath, string outputFilePath,
                                           int targetSampleRate= 8000, int bitRate=32, int channels=1)
        {
            // 验证输入参数
            if (!File.Exists(inputFilePath))
                throw new FileNotFoundException("输入文件不存在", inputFilePath);

            if (string.IsNullOrEmpty(outputFilePath))
                throw new ArgumentException("输出文件路径不能为空");

            if (channels != 1 && channels != 2)
                throw new ArgumentException("声道数必须为1(单声道)或2(立体声)", nameof(channels));

            // 支持的采样率验证(常见MP3采样率)
            int[] supportedSampleRates = { 8000, 11025, 16000, 22050, 32000, 44100, 48000 };
            if (Array.IndexOf(supportedSampleRates, targetSampleRate) == -1)
                throw new ArgumentException("不支持的采样率", nameof(targetSampleRate));

            // 支持的比特率验证(LAME支持的常见比特率)
            if (bitRate < 32 || bitRate > 320 || bitRate % 8 != 0)
                throw new ArgumentException("无效的比特率,必须是32-320之间的8的倍数", nameof(bitRate));

            // 确保输出目录存在
            var outputDir = Path.GetDirectoryName(outputFilePath);
            if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
                Directory.CreateDirectory(outputDir);

            WaveStream reader = null;
            WaveStream resampledStream = null;
            LameMP3FileWriter writer = null;

            try
            {
                // 读取输入音频文件(NAudio会自动识别格式)
                reader = new AudioFileReader(inputFilePath);

                // 如果需要重采样或改变声道数
                if (reader.WaveFormat.SampleRate != targetSampleRate ||
                    reader.WaveFormat.Channels != channels)
                {
                    // 创建重采样器
                    var resampler = new MediaFoundationResampler(reader,
                        WaveFormat.CreateIeeeFloatWaveFormat(targetSampleRate, channels));

                    // 重采样质量设置(0-100,越高质量越好但速度越慢)
                    resampler.ResamplerQuality = 60;
                    resampledStream = new WaveProviderToStreamAdapter(resampler);
                }
                else
                {
                    // 无需重采样,直接使用原始流
                    resampledStream = reader;
                }

                // 初始化LAME编码器设置
                LameConfig lameConfig = new LameConfig();
                lameConfig.BitRate = bitRate;

                // 创建MP3写入器(内部会初始化LAME编码器)
                writer = new LameMP3FileWriter(outputFilePath,
                    resampledStream.WaveFormat,
                    lameConfig);

                // 缓冲区大小(根据采样率调整,确保处理效率)
                var bufferSize = resampledStream.WaveFormat.AverageBytesPerSecond / 4;
                var buffer = new byte[bufferSize];
                int bytesRead;

                // 处理音频数据
                while ((bytesRead = resampledStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    writer.Write(buffer, 0, bytesRead);
                }
            }
            catch (Exception ex)
            {
                // 清理可能生成的不完整文件
                if (File.Exists(outputFilePath))
                    File.Delete(outputFilePath);

                throw new IOException("MP3处理失败", ex);
            }
            finally
            {
                // 确保资源释放
                writer?.Dispose();
                resampledStream?.Dispose();
                reader?.Dispose();
            }
        }
    }

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

月巴月巴白勺合鸟月半

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

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

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

打赏作者

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

抵扣说明:

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

余额充值