Unity资源压缩--图片和音频

我们的图片和音频是在项目中必不可少的资源,随着项目的成长,占比也会越来越大,所以选择带入项目或不带入都要进行压缩.下面是不带入项目式的下载压缩方式
下面先看图片压缩

图片压缩的工具GitHub - ARM-software/astc-encoder: The Arm ASTC Encoder, a compressor for the Adaptive Scalable Texture Compression data format.

参考文档:纹理压缩格式 - Unity 手册 (unity3d.com)

通用路径:

 /// <summary>
 /// windows cmd命令行操作信息
 /// </summary>
 public static class CmdInfo
 {
     //纹理压缩
     public const string compressTexture_draws = @"\draws_astc";
     public const string compressTexture_words = @"\words_astc";
     public const string compress_exe_pic = @"\bin\astcenc-sse4.1.exe";

     //音频压缩
     public const string compressAudio_draws = @"\draws_audio";
     public const string compressAudio_words = @"\words_audio";
     public const string compressAudio_exerciseRead = @"\exerciseRead_audio";
     public const string compressAudio_story = @"\story_audio";
     public const string compress_exe_audio = @"\rollstools\VideoFix\ffmpeg\ffmpeg.exe";

     //批处理
     public const string compressAudio_batch = @"D:\Work\learning\rollstools\VideoFix\audio.bat";
 }

图片压缩执行cmd运行:

 private static (string,string,string) RunCMD_Texture(string resPath ,string inputImagePath,string fileDrawsName,ResType resType)
 {
     var outTopFolder = string.Empty;
     string astcencPath = resPath + CmdInfo.compress_exe_pic;
     var saveName = Path.GetFileNameWithoutExtension(inputImagePath) +".astc";
     if(resType == ResType.DRAWS)
     {
         outTopFolder = resPath + CmdInfo.compressTexture_draws + @"\"+ fileDrawsName;
     }
     else if(resType == ResType.WORDS)
     {
         outTopFolder = resPath + CmdInfo.compressTexture_words + @"\" + fileDrawsName;
     }
     if(!Directory.Exists(outTopFolder))
     {
         Directory.CreateDirectory(outTopFolder);
     }
     string outputAstcPath = outTopFolder + @"\" + saveName;
     // 构建命令行参数
     string arguments = $"-cs \"{inputImagePath}\" \"{outputAstcPath}\" 8x8 -medium -yflip";

     // 启动命令行进程
     ProcessStartInfo startInfo = new ProcessStartInfo(astcencPath, arguments);
     startInfo.CreateNoWindow = true; // 不显示命令行窗口
     startInfo.UseShellExecute = false; // 不用shell程序启动进程
     startInfo.RedirectStandardOutput = true; // 重定向标准输出流

     using (Process process = Process.Start(startInfo))
     {
         // 读取并输出命令行输出
         string output = process.StandardOutput.ReadToEnd();
         Log(arguments + output);
         process.WaitForExit();
     }
     return (outTopFolder,saveName, outputAstcPath);
 }
下面是音频的处理:

下载:FFmpeg

压缩音频需要知道知道音频的基本知识--

采样频率

采样频率是指单位时间内对声音模拟信号的采样次数,采样率类似于视频的帧数,比如电影的采样率是24Hz,当我们把采样到的一个个静止的画面再以采样率同样的速度回放时,看到的就是连续的画面,同样的道理,把以44.1kHz采样率纪录的cd以同样的速率播放时,就能听到连续的声音,显然,这个采样率越高,听到的声音和看到的画面就越连贯,当然,人的听觉和视觉器官能分辨的采样率是有限的,对同一段声音,用20kHz和44.1kHz来采样,重放时,可能可以听出其中的差别,而基本上高于44.1kHZ采样的声音,比如说96kHz采样,绝大部分人已经觉察不到两种采样出来的声音的分别了。之所以使用44.1kHZ这个数值是因为经过了反复实验,人们发现这个采样精度最合适,低于这个值就会有较明显的损失,而高于这个值人的耳朵已经很难分辨,而且增大了数字音频所占用的空间。我们所使用的CD的采样标准就是44.1k

采样位数

采样位数可以理解为采集卡处理声音的解析度。这个数值越大,解析度就越高,录制和回放的声音就越真实。我们首先要知道:电脑中的声音文件是用数字0和1来表示的。连续的模拟信号按一定的采样频率经数码脉冲取样后,每一个离散的脉冲信号被以一定的量化精度量化成一串二进制编码流,这串编码流的位数即为采样位数,也称为量化精度

在电脑上录音的本质就是把模拟声音信号转换成数字信号。反之,在播放时则是把数字信号还原成模拟声音信号输出。采集卡的位是指采集卡在采集和播放声音文件时所使用数字声音信号的二进制位数。采集卡的位客观地反映了数字声音信号对输入声音信号描述的准确程度。例如,同一段音频信息,使用8bit描述单个采样信息,那么采样量化的范围就是0255,如果使用16bit表示单个采样值,那么相应的采样量化的范围为064k。与8位采样位数相比,动态范围更宽广,声音的被记录的更加精细。一般CD使用的采样位数为16位

16位二进制数的最小值是0000000000000000,最大值是1111111111111111,对应的十进制数就是0和65535,也就是最大和最小值之间的差值是65535,也就是说,它量化的模拟量的动态范围可以差65535,也就是96.32分贝(20 * lg65535)),所以,量化精度只和动态范围有关,和频率响应没关系。动态范围定在96分贝也是有道理的,人耳的无痛苦极限声压是90分贝,96分贝的动态范围在普通应用中足够使用,所以96分贝动态范围内的模拟波,经量化后,不会产生削波失真的

位速/比特率/码率

位速/比特率/码率描述的都是一个东西,是指在一个数据流中每秒钟能通过的信息量。我们可能看到过音频文件用 “128–Kbps MP3” 或 “64–Kbps WMA” 进行描述的情形。Kbps 表示 “每秒千位数”,因此数值越大表示数据越多:128–Kbps MP3 音频文件包含的数据量是 64–Kbps WMA 文件的两倍,并占用两倍的空间。(不过在这种情况下,这两种文件听起来没什么两样。原因是什么呢?有些文件格式比其他文件能够更有效地利用数据, 64–Kbps WMA 文件的音质与 128–Kbps MP3 的音质相同。)需要了解的重要一点是,位速越高,信息量越大,对这些信息进行解码的处理量就越大,文件需要占用的空间也就越多

码率=取样频率×量化精度×声道数

一张CD,双声道,采样率44.1kHz,每个采样位数13bit,时长74分钟(4440秒),则CD的容量为13244100*4440约等于640MB。


VBR和CBR的区别--

BR(Variable Bitrate)动态比特率。也就是没有固定的比特率,压缩软件在压缩时根据音频数据即时确定使用什么比特率。这是新发展的算法,他们将一首歌的复杂部分用高Bitrate编码,简单部分用低Bitrate编码。主意虽然不错,可惜新编码器的VBR算法很差,音质与CBR相去甚远。幸运的是, Lame完美地优化了VBR算法,使之成为MP3的最佳编码模式。这是以质量为前提兼顾文件大小的方式,推荐编码模式。

ABR(Average Bitrate)平均比特率,是VBR的一种插值参数。Lame针对CBR不佳的文件体积比和VBR生成文件大小不定的特点独创了这种编码模式。ABR也被称为“Safe VBR”,它是在指定的平均Bitrate内,以每50帧(30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量。举例来说,当指定用192kbps ABR对一段wav文件进行编码时,Lame会将该文件的85%用192kbps固定编码,然后对剩余15%进行动态优化:复杂部分用高于192kbps 来编码、简单部分用低于192kbps来编码。与192kbps CBR相比,192kbps ABR在文件大小上相差不多,音质却提高不少。ABR编码在速度上是VBR编码的2到3倍,在128-256kbps范围内质量要好于CBR。可以做为 VBR和CBR的一种折衷选择。

CBR(Constant Bitrate),常数比特率,指文件从头到尾都是一种位速率。相对于VBR和ABR来讲,它压缩出来的文件体积很大,但音质却不会有明显的提高

例:

采样频率的使用级别

16Kbps=电话音质

24Kbps=增加电话音质、短波广播、长波广播、欧洲制式中波广播

40Kbps=美国制式中波广播

56Kbps=话音

64Kbps=增加话音、手机铃声最佳比特率(Kbps)设定值、手机单声道MP3播放器最佳设定值

112Kbps=FM调频立体声广播

128Kbps=磁带、手机立体声MP3播放器最佳设定值、低档MP3播放器最佳设定值

192Kbps=中档MP3播放器最佳设定值

320Kbps=高档MP3播放器最佳设定值(MP3格式的最高比特率)

550Kbps~16384Kbps=Studio音乐工作室(音乐发烧友适用)

还不懂的请参考FFmpeg的音频处理详解【最详细总结】 - 知乎 (zhihu.com)

下面是使用代码

/// <summary>
/// 运行命令行 压缩音频
/// </summary>
/// <param name="resPath"></param>
/// <param name="fileName"></param>
/// <param name="fileDrawsName"></param>
/// <param name="dRAWS"></param>
/// <exception cref="NotImplementedException"></exception>
private (string,string,string) RunCMD_Audio(string resPath, string inputImagePath, string fileDrawsName, ResType resType)
{
    var outTopFolder = string.Empty;
    string astcencPath = resPath + CmdInfo.compress_exe_audio;
    var saveName = GetFileNameFromPath(inputImagePath);
    if (resType == ResType.DRAWS)
    {
        outTopFolder = resPath + CmdInfo.compressAudio_draws + @"\" + fileDrawsName;
    }
    else if (resType == ResType.WORDS)
    {
        outTopFolder = resPath + CmdInfo.compressAudio_words + @"\" + fileDrawsName;
    }
    else if(resType == ResType.EXERCISEREAD)
    {
        outTopFolder = resPath + CmdInfo.compressAudio_exerciseRead + @"\" + fileDrawsName;
    }
    else if(resType == ResType.STORY)
    {
        outTopFolder = resPath + CmdInfo.compressAudio_story + @"\" + fileDrawsName;
    }
    if (!Directory.Exists(outTopFolder))
    {
        Directory.CreateDirectory(outTopFolder);
    }
    string outputAstcPath = outTopFolder + @"\" + saveName;
    // 构建命令行参数
    string arguments = $"-i \"{inputImagePath}\" -q:a 2 -ar 44100 \"{outputAstcPath}\"";

    // 启动命令行进程
    ProcessStartInfo startInfo = new ProcessStartInfo(astcencPath, arguments);
    startInfo.CreateNoWindow = true; // 不显示命令行窗口
    startInfo.UseShellExecute = false; // 不用shell程序启动进程
    startInfo.RedirectStandardOutput = true; // 重定向标准输出流

    using (Process process = Process.Start(startInfo))
    {
        // 读取并输出命令行输出
        string output = process.StandardOutput.ReadToEnd();
        Log(arguments + output);
        process.WaitForExit();
    }
    return (outTopFolder, saveName, outputAstcPath);
}

最后,希望大家参考文档根据需求进行调整

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值