diff --git a/RMuseum/RMuseum.csproj b/RMuseum/RMuseum.csproj index 9b8135b4..33d81392 100644 --- a/RMuseum/RMuseum.csproj +++ b/RMuseum/RMuseum.csproj @@ -20,7 +20,6 @@ - diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index 5bbe35c9..cda4c7f9 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -4307,11 +4307,6 @@ equaivalnet for persian characters - - - ogg vorbis convertor - - manipulating picture files diff --git a/RMuseum/Services/Implementation/AudioNarrationService.cs b/RMuseum/Services/Implementation/AudioNarrationService.cs index 2659096e..f74f5b61 100644 --- a/RMuseum/Services/Implementation/AudioNarrationService.cs +++ b/RMuseum/Services/Implementation/AudioNarrationService.cs @@ -1,11 +1,8 @@ -using Audit.WebApi; -using ganjoor; +using ganjoor; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MySql.Data.MySqlClient; -using NAudio.Wave; -using OggVorbisEncoder; using RMuseum.DbContext; using RMuseum.Migrations; using RMuseum.Models.GanjoorAudio; @@ -195,9 +192,9 @@ namespace RMuseum.Services.Implementation }; string ext = Path.GetExtension(file.FileName).ToLower(); - if(ext != ".mp3" && ext != ".xml" && ext != ".zip") + if(ext != ".mp3" && ext != ".xml" && ext != ".ogg") { - file.ProcessResultMsg = "تنها فایلهای با پسوند mp3، xml و zip قابل قبول هستند."; + file.ProcessResultMsg = "تنها فایلهای با پسوند mp3، xml و ogg قابل قبول هستند."; } else { @@ -331,6 +328,7 @@ namespace RMuseum.Services.Implementation string localMp3FilePath = Path.Combine(targetPathForAudioFiles, $"{fileNameWithoutExtension}.mp3"); + string localOggFilePath = Path.Combine(targetPathForAudioFiles, $"{fileNameWithoutExtension}.ogg"); UploadSessionFile mp3file = mp3files.Where(mp3 => mp3.MP3FileCheckSum == audio.FileCheckSum).SingleOrDefault(); if(mp3file == null) @@ -341,22 +339,11 @@ namespace RMuseum.Services.Implementation else { File.Move(mp3file.FilePath, localMp3FilePath); + File.Move(Path.Combine(Path.GetDirectoryName(mp3file.FilePath), $"{Path.GetFileNameWithoutExtension(mp3file.FilePath)}.ogg"), localOggFilePath); + int mp3fileSize = File.ReadAllBytes(localMp3FilePath).Length; + int oggfileSize = File.ReadAllBytes(localOggFilePath).Length; - //here we should produce and save ogg file - byte[] mp3bytes = File.ReadAllBytes(Path.Combine(targetPathForAudioFiles, $"{fileNameWithoutExtension}.mp3")); - int mp3fileSize = mp3bytes.Length; - int oggfileSize; - using (MemoryStream ms = new MemoryStream(mp3bytes)) - using (Mp3FileReader mp3FileReader = new Mp3FileReader(ms)) - { - byte[] samples = new byte[mp3FileReader.Length]; - await mp3FileReader.ReadAsync(samples, 0, (int)mp3FileReader.Length); - var oggBytes = OggVorbisConvertor.ConvertRawPCMFile(mp3FileReader.Mp3WaveFormat.SampleRate, mp3FileReader.Mp3WaveFormat.Channels, samples, PCMSample.EightBit, mp3FileReader.Mp3WaveFormat.SampleRate, mp3FileReader.Mp3WaveFormat.Channels); - oggfileSize = oggBytes.Length; - File.WriteAllBytes(Path.Combine(targetPathForAudioFiles, $"{fileNameWithoutExtension}.ogg"), oggBytes); - } - Guid legacyAudioGuid = audio.SyncGuid; while( diff --git a/RMuseum/Services/Implementation/OggVorbisConvertor.cs b/RMuseum/Services/Implementation/OggVorbisConvertor.cs deleted file mode 100644 index 0cca1602..00000000 --- a/RMuseum/Services/Implementation/OggVorbisConvertor.cs +++ /dev/null @@ -1,141 +0,0 @@ -using OggVorbisEncoder; -using System; -using System.IO; - -namespace RMuseum.Services.Implementation -{ - internal enum PCMSample : int - { - EightBit = 1, - SixteenBit = 2 - } - /// - /// ogg vorbis convertor - /// - internal static class OggVorbisConvertor - { - public static byte[] ConvertRawPCMFile(int OutputSampleRate, int OutputChannels, byte[] PCMSamples, PCMSample PCMSampleSize, int PCMSampleRate, int PCMChannels) - { - int NumPCMSamples = (PCMSamples.Length / (int)PCMSampleSize / PCMChannels); - float PCMDuraton = NumPCMSamples / (float)PCMSampleRate; - - int NumOutputSamples = (int)(PCMDuraton * OutputSampleRate); - //Ensure that samble buffer is aligned to write chunk size - NumOutputSamples = (NumOutputSamples / WriteBufferSize) * WriteBufferSize; - - float[][] OutSamples = new float[OutputChannels][]; - - for (int ch = 0; ch < OutputChannels; ch++) - OutSamples[ch] = new float[NumOutputSamples]; - - for (int sampleNumber = 0; sampleNumber < NumOutputSamples; sampleNumber++) - { - float rawSample = 0.0f; - - for (int ch = 0; ch < OutputChannels; ch++) - { - int sampleIndex = (sampleNumber * PCMChannels) * (int)PCMSampleSize; - - if (ch < PCMChannels) sampleIndex += (ch * (int)PCMSampleSize); - - switch (PCMSampleSize) - { - case PCMSample.EightBit: - rawSample = ByteToSample(PCMSamples[sampleIndex]); - break; - case PCMSample.SixteenBit: - rawSample = ShortToSample((short)(PCMSamples[sampleIndex + 1] << 8 | PCMSamples[sampleIndex])); - break; - } - - OutSamples[ch][sampleNumber] = rawSample; - } - } - - return GenerateFile(OutSamples, OutputSampleRate, OutputChannels); - } - - private static float ByteToSample(short pcmValue) - { - return pcmValue / 128f; - } - - private static float ShortToSample(short pcmValue) - { - return pcmValue / 32768f; - } - - private static byte[] GenerateFile(float[][] FloatSamples, int SampleRate, int Channels) - { - using (MemoryStream outputData = new MemoryStream()) - { - // Stores all the static vorbis bitstream settings - var info = VorbisInfo.InitVariableBitRate(Channels, SampleRate, 0.5f); - - // set up our packet->stream encoder - var serial = new Random().Next(); - var oggStream = new OggStream(serial); - - // ========================================================= - // HEADER - // ========================================================= - // Vorbis streams begin with three headers; the initial header (with - // most of the codec setup parameters) which is mandated by the Ogg - // bitstream spec. The second header holds any comment fields. The - // third header holds the bitstream codebook. - var headerBuilder = new HeaderPacketBuilder(); - - var comments = new Comments(); - comments.AddTag("ARTIST", "TEST"); - - var infoPacket = headerBuilder.BuildInfoPacket(info); - var commentsPacket = headerBuilder.BuildCommentsPacket(comments); - var booksPacket = headerBuilder.BuildBooksPacket(info); - - oggStream.PacketIn(infoPacket); - oggStream.PacketIn(commentsPacket); - oggStream.PacketIn(booksPacket); - - // Flush to force audio data onto its own page per the spec - FlushPages(oggStream, outputData, true); - - // ========================================================= - // BODY (Audio Data) - // ========================================================= - var processingState = ProcessingState.Create(info); - - processingState.WriteData(FloatSamples, FloatSamples[0].Length); - for (int readIndex = 0; readIndex <= FloatSamples[0].Length; readIndex += WriteBufferSize) - { - - OggPacket packet; - while (!oggStream.Finished - && processingState.PacketOut(out packet)) - { - oggStream.PacketIn(packet); - - FlushPages(oggStream, outputData, false); - } - } - - FlushPages(oggStream, outputData, true); - - return outputData.ToArray(); - } - } - - private static void FlushPages(OggStream oggStream, Stream Output, bool Force) - { - OggPage page; - while (oggStream.PageOut(out page, Force)) - { - Output.Write(page.Header, 0, page.Header.Length); - Output.Write(page.Body, 0, page.Body.Length); - } - } - - private static int WriteBufferSize = 512; - private static readonly int[] SampleRates = { 8000, 11025, 16000, 22050, 32000, 44100 }; - - } -}