Skip to content

Commit a6f4678

Browse files
committed
- audio - conversion to opus
1 parent e7a26d8 commit a6f4678

File tree

5 files changed

+54
-45
lines changed

5 files changed

+54
-45
lines changed

3dParty/FileSignatures

Botticelli.Audio.Tests/UniversalConvertorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public UniversalConvertorTests()
1515
}
1616

1717
[Test()]
18-
public void ConvertMp3ToMp3Test()
18+
public void ConvertMp3ToOpusTest()
1919
{
2020
if (!File.Exists("voice.mp3"))
2121
Assert.Fail("no voice.mp3!");

Botticelli.Audio/AudioInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public class AudioInfo
44
{
55
public AudioFormat AudioFormat { get; set; }
6-
public int Bitrate => BitsPerSample * SampleRate;
6+
public int Bitrate { get; set; }
77
public int BitsPerSample { get; set; }
88
public int SampleRate { get; set; }
99
public int Channels { get; set; }

Botticelli.Audio/Botticelli.Audio.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="FFMpegCore" Version="5.1.0" />
1011
<PackageReference Include="NAudio" Version="2.2.1" />
1112
<PackageReference Include="NAudio.Lame" Version="2.1.0" />
1213
<PackageReference Include="NAudio.Vorbis" Version="1.5.0" />

Botticelli.Audio/UniversalConvertor.cs

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using NAudio.Lame;
1+
using FFMpegCore;
2+
using FFMpegCore.Enums;
3+
using FFMpegCore.Exceptions;
4+
using FFMpegCore.Pipes;
5+
using NAudio.Lame;
26
using NAudio.Vorbis;
37
using NAudio.Wave;
48

@@ -12,60 +16,64 @@ public class UniversalConvertor : IConvertor
1216

1317
public byte[] Convert(Stream input, AudioInfo targetParams)
1418
{
15-
var srcParams = _analyzer.Analyze(input);
16-
17-
//if (targetParams.AudioFormat == AudioFormat.Opus)
18-
// return ProcessByStreamEncoder<OpusEncoder, OpusAudioEncoderConfiguration>(input, srcParams);
19-
//if (targetParams.AudioFormat == AudioFormat.M4a || targetParams.AudioFormat == AudioFormat.Aac)
20-
// return ProcessByStreamEncoder<AACEncoder, AacAudioEncoderConfiguration>(input, srcParams);
19+
if (targetParams.AudioFormat is AudioFormat.M4a or AudioFormat.Aac or AudioFormat.Opus)
20+
return ProcessByStreamEncoder(input, targetParams);
2121

22+
var srcParams = _analyzer.Analyze(input);
2223

2324
using var resultStream = new MemoryStream();
2425
using var srcStream = GetSourceWaveStream(input, srcParams);
2526
using var tgtStream = GetTargetWaveStream(srcStream, targetParams);
26-
var result = tgtStream.ToArray();
27-
return result;
28-
}
29-
30-
//private static byte[] ProcessByStreamEncoder<TEnc, TConfig>(Stream input, AudioInfo srcParams)
31-
//where TEnc : IAudioEncoderBase, new()
32-
//where TConfig : AudioEncoderConfiguration, new()
33-
//{
34-
// using var enc = new TEnc();
35-
36-
// InitStreamEncoder<TEnc, TConfig>(srcParams, enc);
37-
38-
// using var sr = new BinaryReader(input);
3927

40-
// var bytes = sr.ReadBytes((int)input.Length);
41-
// enc.Transform(new MediaBuffer<byte>(bytes));
42-
43-
// return enc.OutputQueue?.LastOrDefault()?.Buffer?.Array;
44-
//}
28+
return tgtStream.ToArray();
29+
}
4530

46-
//private static void InitStreamEncoder<TEnc, TConfig>(AudioInfo srcParams, TEnc enc)
47-
// where TEnc : IAudioEncoderBase, new()
48-
// where TConfig : AudioEncoderConfiguration, new()
49-
//{
50-
// enc.Init(new TConfig()
51-
// {
52-
// Channels = srcParams.Channels,
53-
// Samplerate = srcParams.SampleRate,
54-
// BitsPerSample = srcParams.BitsPerSample,
55-
// Bitrate = srcParams.Bitrate
56-
// });
57-
//}
31+
private static byte[] ProcessByStreamEncoder(Stream input, AudioInfo tgtParams)
32+
{
33+
try
34+
{
35+
var codec = string.Empty;
36+
input.Seek(0, SeekOrigin.Begin);
37+
38+
switch (tgtParams.AudioFormat)
39+
{
40+
case AudioFormat.Ogg:
41+
codec = "ogg";
42+
break;
43+
case AudioFormat.Aac:
44+
case AudioFormat.M4a:
45+
codec = "aac";
46+
break;
47+
case AudioFormat.Opus:
48+
codec = "opus";
49+
break;
50+
case AudioFormat.Unknown:
51+
default:
52+
throw new ArgumentOutOfRangeException();
53+
}
54+
55+
using var output = new MemoryStream();
56+
FFMpegArguments
57+
.FromPipeInput(new StreamPipeSource(input))
58+
.OutputToPipe(new StreamPipeSink(output), options => options
59+
.ForceFormat(codec)
60+
.WithAudioBitrate(AudioQuality.Low))
61+
.ProcessSynchronously();
62+
63+
return output.ToArray();
64+
}
65+
catch (IOException ex)
66+
{
67+
return Array.Empty<byte>();
68+
}
69+
}
5870

5971
private WaveStream GetSourceWaveStream(Stream input, AudioInfo srcParams)
6072
{
6173
return srcParams.AudioFormat switch
6274
{
6375
AudioFormat.Mp3 => new Mp3FileReader(input),
6476
AudioFormat.Ogg => new VorbisWaveReader(input),
65-
//AudioFormat.Wav => new WaveFileReader(input),
66-
//AudioFormat.Aac => new WaveFileReader(input),
67-
//AudioFormat.M4a => new WaveFileReader(input),
68-
//AudioFormat.Unknown => new WaveFileReader(input),
6977
_ => new WaveFileReader(input)
7078
};
7179
}
@@ -77,7 +85,7 @@ private MemoryStream GetTargetWaveStream(WaveStream input, AudioInfo srcParams)
7785

7886
Stream writerStream = srcParams.AudioFormat switch
7987
{
80-
AudioFormat.Mp3 => new LameMP3FileWriter(ms, input.WaveFormat, LAMEPreset.MEDIUM_FAST),
88+
AudioFormat.Mp3 => new LameMP3FileWriter(ms, input.WaveFormat, LAMEPreset.ABR_16),
8189
//AudioFormat.Wav => new WavFileWriter(input),
8290
//AudioFormat.Aac => new WavFileWriter(input),
8391
//AudioFormat.M4a => new WavFileWriter(input),

0 commit comments

Comments
 (0)