音频转码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了音频转码相关的知识,希望对你有一定的参考价值。
参考技术A 音频这块涉及面广,细节也挺多,以下为针对音频转码部分一、介绍几种压缩编码格式
01、WAV编码
WAV编码的一种实现就是在PCM数据格式的前面加上44字节,分别用来描述PCM的采样率、声道率、数据格式等信息。
特点:音质非常好,大量软件都支持。
使用场合:多媒体开发的中间文件、保存音乐和音效素材。
02、MP3编码
MP3具有不错的压缩比,使用LAME编码(MP3编码格式的一种实现)的中高码率的MP3文件,听感非常接近WAV,当然在不同的应用场景下,应该调整合适的参数以达到最好的效果。特点:音质在128Kbit/s已上表现不错,压缩比比较高,大量软件和硬件都支持,兼容性好。
03、AAC编码
是一种专为声音数据设计的文件压缩格式。与 MP3 不同,它采用了全新的算法进行编码,更加高效,具有更高的“性价比”。利用AAC格式,可使人感觉声音质量没有明显降低的前提下,更加小巧。 苹果ipod 、 诺基亚 手机支持AAC格式的音频文件。
特点:在小于128kBIT/s一下的音频编码,多用于视频中音轨的编码。
04、OGG编码
Ogg是一种非常有潜力的编码,在各种码率下都有比较优秀的表现,尤其在中低码率场景下。Ogg除了音质很好,还是完全免费的。ogg有着出色的算法,可以用更小的码率达到更好的音质。Ogg目前支持的情况还不够好,无论软件还是硬件,都无法和MP3相提并论。
特点:可以用比MP3更小的码率实现比MP3更好的音质,高中低码率下均有良好的表现,兼容性不够好,流媒体特性不支持。
使用场合:语音聊天的音频消息场景
二、ios音频处理各个框架
AVAudioPlayer
基本操作:播放、暂停、停止、循环等等一些基本的音频播放功能。
控制:可对音频进行任意时间位置播放;进度控制。
其它:*从文件或缓冲区播放声音;获取音视频关键参数,如音频标题、作者、功率等等。
三、录音设置
//录音设置
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc]init];
//设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
//设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量)
[recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];
//录音通道数 1 或 2
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
//线性采样位数 8、16、24、32
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
//录音的质量
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
注意:如果WAV转MP3通道数目需设置为2,否则转码后声音不对(音色、音质都会变质),录音的采样率和转码的采样率需保持一致,AVNumberOfChannelsKey设置为2时,文件同时会增加一倍;如果设置默认为MP3则会失败。
使用带有 C# 的 MediaTranscoder 将 PCM 音频转码为 MP3
【中文标题】使用带有 C# 的 MediaTranscoder 将 PCM 音频转码为 MP3【英文标题】:Transcode PCM Audio to MP3 using MediaTranscoder with C# 【发布时间】:2019-11-04 20:32:15 【问题描述】:我正在尝试对从 WebRTC 调用中保存的 PCM 格式的音频文件进行转码。 WebRTC 报告的音频流格式为 16 位深度、1 通道和 48000 Hz 采样率。我想将音频转换为 MP3,以便之后可以将音频作为背景音轨添加到我的 Unity UWP 应用程序的屏幕录制中(使用 MediaComposition)。我在第一部分遇到问题:尝试将我的 PCM 音频文件转码为 MP3 文件。当我尝试准备转码时,preparedTranscodeResult.CanTranscode
正在返回 false
。以下是我的代码。
StorageFile remoteAudioPCMFile = await StorageFile.GetFileFromPathAsync(Path.Combine(Application.temporaryCachePath, "remote.pcm").Replace("/", "\\"));
StorageFolder tempFolder = await StorageFolder.GetFolderFromPathAsync(Application.temporaryCachePath.Replace("/", "\\"));
StorageFile remoteAudioMP3File = await tempFolder.CreateFileAsync("remote.mp3", CreationCollisionOption.ReplaceExisting);
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto);
profile.Audio.BitsPerSample = 16;
profile.Audio.ChannelCount = 1;
profile.Audio.SampleRate = 48000;
MediaTranscoder transcoder = new MediaTranscoder();
var preparedTranscodeResult = await transcoder.PrepareFileTranscodeAsync(remoteAudioPCMFile, remoteAudioMP3File, profile);
if (preparedTranscodeResult.CanTranscode)
await preparedTranscodeResult.TranscodeAsync();
else
if (remoteAudioPCMFile != null)
await remoteAudioPCMFile.DeleteAsync();
if (remoteAudioMP3File != null)
await remoteAudioMP3File.DeleteAsync();
switch (preparedTranscodeResult.FailureReason)
case TranscodeFailureReason.CodecNotFound:
Debug.LogError("Codec not found.");
break;
case TranscodeFailureReason.InvalidProfile:
Debug.LogError("Invalid profile.");
break;
default:
Debug.LogError("Unknown failure.");
break;
【问题讨论】:
您的开关盒中是否有任何日志?您是否尝试过转码? 您好,我测试了一些不同类型的音频文件,只有 pcm 无法正确转码,并且无法提供有效的错误信息。MediaTranscode
现在可能无法直接转码 pcm 音频文件。我正在寻求工程师的帮助,看看是否有其他解决方案。
@LouisGarczynski 是的,它转到默认情况并打印“未知故障”。
@RichardZhang-MSFT 好的,谢谢!对此,我真的非常感激!我希望先使用 ffmpeg,但您无法在 UWP 中启动外部进程。
如果您可以访问该文件,为什么不使用任何类型的在线转换器来获取 mp3?
【参考方案1】:
所以我必须在开始将数据写入流之前将标头写入我的FileStream
。我是从this post 那里得到的。
private void WriteWavHeader(FileStream stream, bool isFloatingPoint, ushort channelCount, ushort bitDepth, int sampleRate, int totalSampleCount)
stream.Position = 0;
// RIFF header.
// Chunk ID.
stream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4);
// Chunk size.
stream.Write(BitConverter.GetBytes((bitDepth / 8 * totalSampleCount) + 36), 0, 4);
// Format.
stream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4);
// Sub-chunk 1.
// Sub-chunk 1 ID.
stream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4);
// Sub-chunk 1 size.
stream.Write(BitConverter.GetBytes(16), 0, 4);
// Audio format (floating point (3) or PCM (1)). Any other format indicates compression.
stream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2);
// Channels.
stream.Write(BitConverter.GetBytes(channelCount), 0, 2);
// Sample rate.
stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
// Bytes rate.
stream.Write(BitConverter.GetBytes(sampleRate * channelCount * (bitDepth / 8)), 0, 4);
// Block align.
stream.Write(BitConverter.GetBytes(channelCount * (bitDepth / 8)), 0, 2);
// Bits per sample.
stream.Write(BitConverter.GetBytes(bitDepth), 0, 2);
// Sub-chunk 2.
// Sub-chunk 2 ID.
stream.Write(Encoding.ASCII.GetBytes("data"), 0, 4);
// Sub-chunk 2 size.
stream.Write(BitConverter.GetBytes(bitDepth / 8 * totalSampleCount), 0, 4);
【讨论】:
以上是关于音频转码的主要内容,如果未能解决你的问题,请参考以下文章
Lambda 上的 FFmpeg 转码导致无法使用(静态)音频