本人并不干這個,但是被迫下水了解了一下這個,稍微做了一下整理。再就是感覺現在網上以及ChatGPT在這方面給出的答案太水了,在此開辟一篇。無意放出代碼,這里只介紹一些可能重要的點。
本來以為有了ChatGPT寫這些就沒有必要了,現在看起來還是不太可能。
- 一是知識稍微舊了一點,新一點的沒有,比如github上近一年更新的優秀項目100%是不會出現在解決方案中的。追求能用是不影響的,但是想找最好的有點難。
- 二是方案缺少出處,擴展溯源困難。
- 三是多方案比較困難,不易從中選取出最好的方案。
- 四是幻覺太多,驗證成本太高。
1. 解碼
這里將解碼定義為將有損/無損的(壓縮)格式,比如 mp3/aac 等等轉換到 pcm/wav 這種原始數據的格式的操作,供下游使用。
原始數據可以理解為 采樣率 × 位深度 × 通道數 × 音頻時長 的數據,不加其它處理。
2. 基本參數
來自 javax.sound.sampled.AudioFormat
,先要理解記住這些才能夠有良好掌控
- encoding – the audio encoding technique
- sampleRate – the number of samples per second
- sampleSizeInBits – the number of bits in each sample
- channels – the number of channels (1 for mono, 2 for stereo, and so on)
- frameSize – the number of bytes in each frame
- frameRate – the number of frames per second
- bigEndian – indicates whether the data for a single sample is stored in big-endian byte order
3. FFmpeg
A complete, cross-platform solution to record, convert and stream audio and video.
可能是最強的功能非常齊全,離線格式轉換命令行就用它了,但是要注意ffmpeg在做轉換時有不少參數直接默認了,使用代碼轉換可能有各種對不上(所以需要對參數的理解)。
常見音頻編碼都是確定性編碼,不要自欺欺人覺得大小不一致還是正常的,得每一個byte都一樣才正常。
4. javax.sound.sampled
- 支持PCM/WAV之類的原始音頻格式
- service provider: 在實現之后能夠自動發現和支持更多格式
5. hendriks73/ffsampledsp
有了1-4的鋪墊之后就只需要一個優秀項目來完成剩余的工作了,目前看起來FFSampledSP是最佳選擇(之一,服務器的)
FFSampledSP is an implementation of the javax.sound.sampled service provider interfaces based on FFmpeg, a complete, cross-platform solution to record, convert and stream audio and video. FFSampledSP is part of the SampledSP collection of
javax.sound.sampled
libraries.
- 相當于引入了ffmepg的能力,在已有的庫中實現得是相當好的了。
- 解碼流的時候需要調試參數,可以先校驗是否能轉換
AudioInputStream fileStream = AudioSystem.getAudioInputStream(file); AudioFormat sourceFormat = fileStream.getFormat(); log.info("in audio format: {}", aacFormat); AudioFormat targetFormat = new AudioFormat(); AudioSystem.isConversionSupported(sourceFormat, targetFormat); // 需要為true
- 引入依賴即可,并無太多需要注意的。也就是知識要得挺多,使用起來反而沒什么。