Skip to content

Commit 77cbe45

Browse files
committed
- mp3 convertor
1 parent 56342f8 commit 77cbe45

File tree

8 files changed

+115
-81
lines changed

8 files changed

+115
-81
lines changed
Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,74 @@
11
using NUnit.Framework;
22

3-
namespace Botticelli.Audio.Tests
3+
namespace Botticelli.Audio.Tests;
4+
5+
[TestFixture]
6+
public class UniversalLowQualityConvertorTests
47
{
5-
[TestFixture()]
6-
public class UniversalLowQualityConvertorTests
8+
private readonly IConvertor _convertor;
9+
private readonly IAnalyzer _analyzer;
10+
11+
public UniversalLowQualityConvertorTests()
712
{
8-
private readonly IConvertor _convertor;
9-
private readonly IAnalyzer _analyzer;
13+
_analyzer = new InputAnalyzer();
14+
_convertor = new UniversalLowQualityConvertor(_analyzer);
15+
}
1016

11-
public UniversalLowQualityConvertorTests()
17+
[Test]
18+
public void ConvertMp3ToOpusTest()
19+
{
20+
Check();
21+
var outcome = GetOutcome(new AudioInfo
1222
{
13-
_analyzer = new InputAnalyzer();
14-
_convertor = new UniversalLowQualityConvertor(_analyzer);
15-
}
23+
AudioFormat = AudioFormat.Opus,
24+
Bitrate = AudioBitrate.LowVoice
25+
});
26+
27+
AssertOutcome(outcome);
28+
}
1629

17-
[Test()]
18-
public void ConvertMp3ToOpusTest()
30+
private static void AssertOutcome(byte[] outcome)
31+
{
32+
Assert.NotNull(outcome);
33+
Assert.IsNotEmpty(outcome);
34+
}
35+
36+
private byte[] GetOutcome(AudioInfo audioInfo)
37+
{
38+
using var stream = File.OpenRead("voice.mp3");
39+
var outcome = _convertor.Convert(stream, audioInfo);
40+
return outcome;
41+
}
42+
43+
private static void Check()
44+
{
45+
if (!File.Exists("voice.mp3"))
46+
Assert.Fail("no voice.mp3!");
47+
}
48+
49+
[Test]
50+
public void ConvertMp3ToOggTest()
51+
{
52+
Check();
53+
var outcome = GetOutcome(new AudioInfo
1954
{
20-
if (!File.Exists("voice.mp3"))
21-
Assert.Fail("no voice.mp3!");
22-
using var stream = File.OpenRead("voice.mp3");
23-
var outcome = _convertor.Convert(stream, new AudioInfo()
24-
{
25-
AudioFormat = AudioFormat.Mp3,
26-
Channels = 2,
27-
SampleRate = 8000,
28-
BitsPerSample = 8
29-
});
30-
31-
Assert.NotNull(outcome);
32-
Assert.IsNotEmpty(outcome);
33-
}
34-
35-
[Test()]
36-
public void ConvertMp3ToOggTest()
55+
AudioFormat = AudioFormat.Ogg,
56+
Bitrate = AudioBitrate.VkAudioMessage
57+
});
58+
59+
AssertOutcome(outcome);
60+
}
61+
62+
[Test]
63+
public void ConvertMp3ToMp3LowTest()
64+
{
65+
Check();
66+
var outcome = GetOutcome(new AudioInfo
3767
{
38-
if (!File.Exists("voice.mp3"))
39-
Assert.Fail("no voice.mp3!");
40-
using var stream = File.OpenRead("voice.mp3");
41-
var outcome = _convertor.Convert(stream, new AudioInfo()
42-
{
43-
AudioFormat = AudioFormat.Ogg,
44-
Channels = 2,
45-
SampleRate = 8000,
46-
BitsPerSample = 8
47-
});
48-
49-
Assert.NotNull(outcome);
50-
Assert.IsNotEmpty(outcome);
51-
}
68+
AudioFormat = AudioFormat.Mp3,
69+
Bitrate = AudioBitrate.LowVoice
70+
});
71+
72+
AssertOutcome(outcome);
5273
}
5374
}

Botticelli.Audio/AudioBitrate.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Botticelli.Audio;
2+
3+
public static class AudioBitrate
4+
{
5+
public const int VkAudioMessage = 64;
6+
public const int LowVoice = 8;
7+
public const int MiddleVoice = 16;
8+
public const int HiVoice = 22;
9+
public const int LowMusic = 32;
10+
public const int MiddleMusic = 128;
11+
public const int HiMusic = 256;
12+
}

Botticelli.Audio/IConvertor.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
namespace Botticelli.Audio;
22

3+
/// <summary>
4+
/// Converts to different audio formats
5+
/// </summary>
36
public interface IConvertor
47
{
8+
/// <summary>
9+
/// Converts an input stream
10+
/// </summary>
11+
/// <param name="input"></param>
12+
/// <param name="targetParams"></param>
13+
/// <returns></returns>
514
public byte[] Convert(Stream input, AudioInfo targetParams);
15+
/// <summary>
16+
/// Converts an input byte array
17+
/// </summary>
18+
/// <param name="input"></param>
19+
/// <param name="targetParams"></param>
20+
/// <returns></returns>
621
public byte[] Convert(byte[] input, AudioInfo targetParams);
722
}

Botticelli.Audio/UniversalLowQualityConvertor.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Botticelli.Audio.Exceptions;
22
using FFMpegCore;
3-
using FFMpegCore.Enums;
43
using FFMpegCore.Pipes;
54
using NAudio.Lame;
65
using NAudio.Vorbis;
@@ -74,8 +73,7 @@ private static byte[] ProcessByStreamEncoder(Stream input, AudioInfo tgtParams)
7473
.FromPipeInput(new StreamPipeSource(input))
7574
.OutputToPipe(new StreamPipeSink(output), options => options
7675
.ForceFormat(codec)
77-
.WithAudioBitrate(16000)
78-
.WithAudioBitrate(AudioQuality.Low))
76+
.WithAudioBitrate(tgtParams.Bitrate))
7977
.ProcessSynchronously();
8078

8179
return output.ToArray();
@@ -104,10 +102,6 @@ private MemoryStream GetTargetWaveStream(WaveStream input, AudioInfo srcParams)
104102
Stream writerStream = srcParams.AudioFormat switch
105103
{
106104
AudioFormat.Mp3 => new LameMP3FileWriter(ms, input.WaveFormat, LAMEPreset.ABR_16),
107-
//AudioFormat.Wav => new WavFileWriter(input),
108-
//AudioFormat.Aac => new WavFileWriter(input),
109-
//AudioFormat.M4a => new WavFileWriter(input),
110-
//AudioFormat.Unknown => new WavFileWriter(input),
111105
_ => new WaveFileWriter(ms, input.WaveFormat)
112106
};
113107

Botticelli.Framework.Vk/VkStorageUploader.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,7 @@ private async Task<UploadDocResult> UploadAudioMessage(string uploadUrl, string
174174
// convert to ogg in order to meet VK requirements
175175
var oggContent = _audioConvertor.Convert(binaryContent, new AudioInfo()
176176
{
177-
AudioFormat = AudioFormat.Ogg,
178-
Bitrate = 16000
177+
AudioFormat = AudioFormat.Ogg
179178
});
180179

181180
return await PushDocument<UploadDocResult>(uploadUrl, name, oggContent, token);

Botticelli.Framework/Commands/Processors/CommandProcessor.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,21 @@
99
namespace Botticelli.Framework.Commands.Processors;
1010

1111
public abstract class CommandProcessor<TCommand> : ICommandProcessor
12-
where TCommand : class, ICommand
12+
where TCommand : class, ICommand
1313
{
1414
private const string SimpleCommandPattern = @"\/([a-zA-Z0-9]*)$";
1515
private const string ArgsCommandPattern = @"\/([a-zA-Z0-9]*) (.*)";
1616
private readonly string _commandName;
17-
protected readonly ILogger Logger;
18-
protected readonly ICommandValidator<TCommand> Validator;
19-
protected IList<IBot> Bots = new List<IBot>(10);
17+
protected readonly IList<IBot> Bots = new List<IBot>(10);
18+
private readonly ILogger _logger;
19+
private readonly ICommandValidator<TCommand> _validator;
2020
protected IServiceProvider Sp;
2121

2222
protected CommandProcessor(ILogger logger,
23-
ICommandValidator<TCommand> validator)
23+
ICommandValidator<TCommand> validator)
2424
{
25-
Logger = logger;
26-
Validator = validator;
25+
_logger = logger;
26+
_validator = validator;
2727
_commandName = GetCommandName(typeof(TCommand).Name);
2828
}
2929

@@ -40,7 +40,7 @@ public async Task ProcessAsync(Message message, CancellationToken token)
4040
message.Contact == default &&
4141
message.Poll == default)
4242
{
43-
Logger.LogWarning("Message {msgId} is empty! Skipping...", message.Uid);
43+
_logger.LogWarning("Message {msgId} is empty! Skipping...", message.Uid);
4444

4545
return;
4646
}
@@ -50,7 +50,7 @@ public async Task ProcessAsync(Message message, CancellationToken token)
5050
if (Regex.IsMatch(message.Body, SimpleCommandPattern))
5151
{
5252
var match = Regex.Matches(message.Body, SimpleCommandPattern)
53-
.FirstOrDefault();
53+
.FirstOrDefault();
5454

5555
var commandName = GetCommandName(match.Groups[1].Value);
5656

@@ -59,24 +59,24 @@ public async Task ProcessAsync(Message message, CancellationToken token)
5959
if (match == default) return;
6060

6161
await ValidateAndProcess(message,
62-
string.Empty,
63-
token,
64-
request);
62+
string.Empty,
63+
token,
64+
request);
6565
}
6666
else if (Regex.IsMatch(message.Body, ArgsCommandPattern))
6767
{
6868
var match = Regex.Matches(message.Body, ArgsCommandPattern)
69-
.FirstOrDefault();
69+
.FirstOrDefault();
7070
var argsString = match.Groups[2].Value;
7171

7272
var commandName = GetCommandName(match.Groups[1].Value);
7373

7474
if (commandName != _commandName) return;
7575

7676
await ValidateAndProcess(message,
77-
argsString,
78-
token,
79-
request);
77+
argsString,
78+
token,
79+
request);
8080
}
8181

8282
if (message.Location != default) await InnerProcessLocation(message, string.Empty, token);
@@ -85,7 +85,7 @@ await ValidateAndProcess(message,
8585
}
8686
catch (Exception ex)
8787
{
88-
Logger.LogError(ex, $"Error in {GetType().Name}: {ex.Message}");
88+
_logger.LogError(ex, $"Error in {GetType().Name}: {ex.Message}");
8989
}
9090
}
9191

@@ -99,17 +99,17 @@ public string GetCommandName(string fullCommand)
9999
=> fullCommand.ToLowerInvariant().Replace("command", "");
100100

101101
private async Task ValidateAndProcess(Message message,
102-
string args,
103-
CancellationToken token,
104-
SendMessageRequest request)
102+
string args,
103+
CancellationToken token,
104+
SendMessageRequest request)
105105
{
106-
if (await Validator.Validate(message.ChatIds, message.Body))
106+
if (await _validator.Validate(message.ChatIds, message.Body))
107107
{
108108
await InnerProcess(message, args, token);
109109
}
110110
else
111111
{
112-
request.Message.Body = Validator.Help();
112+
request.Message.Body = _validator.Help();
113113

114114
foreach (var bot in Bots) await bot.SendMessageAsync(request, token);
115115
}

Botticelli.sln

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "front", "front", "{7FF17C87
9898
deploy\linux\server\front\run_standalone.sh = deploy\linux\server\front\run_standalone.sh
9999
EndProjectSection
100100
EndProject
101-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Botticelli.Bundle", "Botticelli.Bundle\Botticelli.Bundle.csproj", "{F400F638-EC58-49A2-B730-BD2688FCD4E9}"
102-
EndProject
103101
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{5961DAF1-951C-4140-AEC1-648539E4D487}"
104102
ProjectSection(SolutionItems) = preProject
105103
docs\site\docs_structure.txt = docs\site\docs_structure.txt
@@ -267,10 +265,6 @@ Global
267265
{2423A645-22D1-4736-946F-10A99353581C}.Debug|Any CPU.Build.0 = Debug|Any CPU
268266
{2423A645-22D1-4736-946F-10A99353581C}.Release|Any CPU.ActiveCfg = Release|Any CPU
269267
{2423A645-22D1-4736-946F-10A99353581C}.Release|Any CPU.Build.0 = Release|Any CPU
270-
{F400F638-EC58-49A2-B730-BD2688FCD4E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
271-
{F400F638-EC58-49A2-B730-BD2688FCD4E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
272-
{F400F638-EC58-49A2-B730-BD2688FCD4E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
273-
{F400F638-EC58-49A2-B730-BD2688FCD4E9}.Release|Any CPU.Build.0 = Release|Any CPU
274268
{343922EC-2CF3-4C0E-B745-08F2B333B4E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
275269
{343922EC-2CF3-4C0E-B745-08F2B333B4E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
276270
{343922EC-2CF3-4C0E-B745-08F2B333B4E3}.Release|Any CPU.ActiveCfg = Release|Any CPU

Botticelli/Services/BotManagementService.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ public async Task RemoveBot(string botId)
153153
/// <param name="botId"></param>
154154
/// <param name="botKey"></param>
155155
/// <param name="botName"></param>
156-
/// <param name="botType"></param>
157156
/// <param name="additionalParams"></param>
158157
/// <returns></returns>
159158
public async Task<bool> UpdateBot(string botId,
@@ -166,7 +165,7 @@ public async Task<bool> UpdateBot(string botId,
166165
_logger.LogInformation($"{nameof(UpdateBot)}({botId}, {botKey}, {botName}) started...");
167166

168167
var prevStatus = await GetRequiredBotStatus(botId);
169-
if (prevStatus == default || prevStatus != BotStatus.NonActive)
168+
if (prevStatus is not BotStatus.NonActive)
170169
await SetRequiredBotStatus(botId, BotStatus.NonActive);
171170

172171
botKey ??= _secureStorage.GetBotContext(botId)?.BotKey;

0 commit comments

Comments
 (0)