protected override void WriteStream(Stream stream) { var oggStream = new OpusOggWriteStream(stream, Format.SampleRate, Format.ChannelCount, Format.PreSkipCount, Format.SampleCount); foreach (OpusFrame frame in Format.Frames) { oggStream.WriteSamples(frame); } oggStream.Finish(); }
public static void Main(string[] args) { string opusfile = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol.opus"; string rawFile = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol.raw"; string rawFile2 = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol_out.raw"; using (FileStream fileOut = new FileStream(opusfile, FileMode.Create)) { OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); encoder.Bitrate = 96000; OpusTags tags = new OpusTags(); tags.Fields[OpusTagName.Title] = "Prisencolinensinainciusol"; tags.Fields[OpusTagName.Artist] = "Adriano Celetano"; OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, fileOut, tags); byte[] allInput = File.ReadAllBytes(rawFile); short[] samples = BytesToShorts(allInput); oggOut.WriteSamples(samples, 0, samples.Length); oggOut.Finish(); } using (FileStream fileIn = new FileStream(opusfile, FileMode.Open)) { using (FileStream fileOut = new FileStream(rawFile2, FileMode.Create)) { OpusDecoder decoder = OpusDecoder.Create(48000, 2); OpusOggReadStream oggIn = new OpusOggReadStream(decoder, fileIn); while (oggIn.HasNextPacket) { short[] packet = oggIn.DecodeNextPacket(); if (packet != null) { byte[] binary = ShortsToBytes(packet); fileOut.Write(binary, 0, binary.Length); } } } } }
private void ConvertToOgg(string uri, string fileLocation, string FileName) { MediaFoundationReader reader = new MediaFoundationReader(uri); WaveFormat newFormat = new WaveFormat(48000, reader.WaveFormat.Channels); WaveFormatConversionStream newStream = new WaveFormatConversionStream(newFormat, reader); WaveStream conv = WaveFormatConversionStream.CreatePcmStream(newStream); byte[] bytes = new byte[conv.Length]; conv.Position = 0; conv.Read(bytes, 0, (int)conv.Length); OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); var memo = new MemoryStream(); var oggOut = new OpusOggWriteStream(encoder, memo); var shorts = ByteToShort(bytes); oggOut.WriteSamples(shorts, 0, shorts.Count()); oggOut.Finish(); var result = memo.ToArray(); using (var stream = new FileStream(fileLocation + FileName, FileMode.Create)) { stream.Write(result, 0, result.Length); } }
public MusicVersion ConvertTrack(MusicTrack musicTrack) { var path = Path.Combine(folderPath, musicTrack.Id + ".ogg"); var wavPath = musicTrack.MusicVersions.SingleOrDefault(p => p.Extension == "wav"); byte[] bytes = ReadAllBytes(wavPath.TrackPath); using (var fileOut = new FileStream(path, FileMode.Create)) { var encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); var oggOut = new OpusOggWriteStream(encoder, fileOut); //byte[] allInput = File.ReadAllBytes(wavPath.TrackPath); short[] samples = BytesToShorts(bytes); oggOut.WriteSamples(samples, 0, samples.Length); oggOut.Finish(); } return(new MusicVersion() { MusicTrack = musicTrack, TrackPath = path, Extension = "ogg" }); }
private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null) { int channels = 2; int samplingRate = 48000; List <uint> chapters = new List <uint>(); var outFormat = new WaveFormat(samplingRate, 2); OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); encoder.Bitrate = bitRate; encoder.UseVBR = useVbr; if (audioId == 0) { audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); } using (MemoryStream outputData = new MemoryStream()) { byte[] buffer = new byte[2880 * channels * 2]; OpusTags tags = new OpusTags(); tags.Comment = "Lavf56.40.101"; tags.Fields["encoder"] = "opusenc from opus-tools 0.1.9"; tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr"; tags.Fields["pad"] = new string('0', 0x138); OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId); uint lastIndex = 0; int track = 0; foreach (var sourceFile in sourceFiles) { try { int bytesReturned = 1; int totalBytesRead = 0; track++; chapters.Add(lastIndex); int lastPct = 0; int snipLen = 15; string displayName = new FileInfo(sourceFile).Name; try { var tag = new Mp3(sourceFile, Mp3Permissions.Read).GetAllTags().FirstOrDefault(); if (tag != null && tag.Title.IsAssigned) { displayName = tag.Title.Value; } } catch (Exception ex) { } string shortName = displayName.PadRight(snipLen).Substring(0, snipLen); Console.Write(" Track " + track.ToString().PadLeft(3) + " - " + shortName + " ["); /* prepend a audio file for e.g. chapter number */ if (prefixLocation != null) { string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3"); if (!File.Exists(prefixFile)) { throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'"); } try { var prefixStream = new Mp3FileReader(prefixFile); var prefixResampled = new MediaFoundationResampler(prefixStream, outFormat); while (true) { bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } } catch (Exception ex) { throw new Exception("Failed processing prefix file '" + prefixFile + "'"); } } /* then the real audio file */ var stream = new Mp3FileReader(sourceFile); var streamResampled = new MediaFoundationResampler(stream, outFormat); while (true) { bytesReturned = streamResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } totalBytesRead += bytesReturned; float progress = (float)stream.Position / stream.Length; if ((int)(progress * 20) != lastPct) { lastPct = (int)(progress * 20); if (lastPct % 5 == 0) { if (lastPct != 20) { Console.Write("" + (lastPct * 5) + "%"); } } else { Console.Write("."); } } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } Console.WriteLine("]"); stream.Close(); } catch (OpusOggWriteStream.PaddingException e) { Console.WriteLine(); throw new EncodingException("Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps"); } catch (FileNotFoundException e) { Console.WriteLine(); throw new FileNotFoundException(e.Message); } catch (InvalidDataException e) { Console.WriteLine(); throw new Exception("Failed processing " + sourceFile); } catch (Exception e) { Console.WriteLine(); throw new Exception("Failed processing " + sourceFile); } } oggOut.Finish(); Audio = outputData.ToArray(); var prov = new SHA1CryptoServiceProvider(); Header.Hash = prov.ComputeHash(Audio); Header.AudioChapters = chapters.ToArray(); Header.AudioId = oggOut.LogicalStreamId; Header.AudioLength = Audio.Length; Header.Padding = new byte[0]; } }
private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null, EncodeCallback cbr = null) { int channels = 2; int samplingRate = 48000; List <uint> chapters = new List <uint>(); var outFormat = new WaveFormat(samplingRate, 2); if (cbr == null) { cbr = new EncodeCallback(); } OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); encoder.Bitrate = bitRate; encoder.UseVBR = useVbr; if (audioId == 0) { audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); } string tempName = Path.GetTempFileName(); using (Stream outputData = new FileStream(tempName, FileMode.OpenOrCreate)) { byte[] buffer = new byte[2880 * channels * 2]; OpusTags tags = new OpusTags(); tags.Comment = "Lavf56.40.101"; tags.Fields["encoder"] = "opusenc from opus-tools 0.1.9"; tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr"; tags.Fields["pad"] = new string('0', 0x138); OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId); uint lastIndex = 0; int track = 0; bool warned = false; long maxSize = 0x77359400; foreach (var sourceFile in sourceFiles) { if ((outputData.Length + 0x1000) >= maxSize) { cbr.Warning("Close to 2 GiB, stopping"); break; } try { int bytesReturned = 1; int totalBytesRead = 0; track++; chapters.Add(lastIndex); int lastPct = 0; cbr.FileStart(track, sourceFile); /* prepend a audio file for e.g. chapter number */ if (prefixLocation != null) { string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3"); if (!File.Exists(prefixFile)) { throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'"); } try { var prefixStream = new Mp3FileReader(prefixFile); var prefixResampled = new MediaFoundationResampler(prefixStream, outFormat); while (true) { bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); if ((outputData.Length + 0x1000 + sampleBuffer.Length) >= maxSize) { break; } oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } } catch (Exception ex) { throw new Exception("Failed processing prefix file '" + prefixFile + "'"); } } /* then the real audio file */ var stream = new Mp3FileReader(sourceFile); var streamResampled = new MediaFoundationResampler(stream, outFormat); while (true) { bytesReturned = streamResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } totalBytesRead += bytesReturned; decimal progress = (decimal)stream.Position / stream.Length; if ((int)(progress * 20) != lastPct) { lastPct = (int)(progress * 20); cbr.Progress(progress); } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } cbr.FileDone(); stream.Close(); } catch (OpusOggWriteStream.PaddingException e) { string msg = "Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps"; cbr.Failed(msg); throw new EncodingException(msg); } catch (FileNotFoundException e) { cbr.Failed(e.Message); throw new FileNotFoundException(e.Message); } catch (InvalidDataException e) { string msg = "Failed processing " + sourceFile; cbr.Failed(msg); throw new Exception(msg); } catch (Exception e) { string msg = "Failed processing " + sourceFile; cbr.Failed(msg); throw new Exception(msg); } if (!warned && outputData.Length >= maxSize / 2) { cbr.Warning("Approaching 2 GiB, please reduce the bitrate"); warned = true; } } oggOut.Finish(); Header.AudioId = oggOut.LogicalStreamId; } Audio = File.ReadAllBytes(tempName); var prov = new SHA1CryptoServiceProvider(); Header.Hash = prov.ComputeHash(Audio); Header.AudioChapters = chapters.ToArray(); Header.AudioLength = Audio.Length; Header.Padding = new byte[0]; File.Delete(tempName); }
private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null) { int channels = 2; int samplingRate = 48000; List <uint> chapters = new List <uint>(); var outFormat = new WaveFormat(samplingRate, 2); OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); encoder.Bitrate = bitRate; encoder.UseVBR = useVbr; if (audioId == 0) { audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); } string tempName = Path.GetTempFileName(); using (Stream outputData = new FileStream(tempName, FileMode.OpenOrCreate)) { byte[] buffer = new byte[2880 * channels * 2]; OpusTags tags = new OpusTags(); tags.Comment = "Lavf56.40.101"; tags.Fields["encoder"] = "opusenc from opus-tools 0.1.9"; tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr"; tags.Fields["pad"] = new string('0', 0x138); OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId); uint lastIndex = 0; int track = 0; bool warned = false; long maxSize = 0x77359400; foreach (var sourceFile in sourceFiles) { if ((outputData.Length + 0x1000) >= maxSize) { Console.WriteLine("Error: Close to 2 GiB, aborting"); break; } try { int bytesReturned = 1; int totalBytesRead = 0; track++; chapters.Add(lastIndex); int lastPct = 0; int snipLen = 15; string displayName = new FileInfo(sourceFile).Name; try { var tag = new Mp3(sourceFile, Mp3Permissions.Read).GetAllTags().FirstOrDefault(); if (tag != null && tag.Title.IsAssigned) { displayName = tag.Title.Value; } } catch (Exception ex) { } string shortName = displayName.PadRight(snipLen).Substring(0, snipLen); Console.Write(" Track " + track.ToString().PadLeft(3) + " - " + shortName + " ["); /* prepend a audio file for e.g. chapter number */ if (prefixLocation != null) { string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3"); if (!File.Exists(prefixFile)) { throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'"); } try { Stream prefixResampled = new MemoryStream(); // Linux string prefixTmpWavFile = ""; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { prefixTmpWavFile = Path.ChangeExtension(Path.GetTempFileName(), "wav"); //Console.Write(" Convert file " + sourceFile + " to WAV. Temp file " + prefixTmpWavFile); // The isReady flag and error test variables are not a nice solution but is working bool isReadyPrefix = false; String FFmpegErrorTextPrefix = ""; // Convert to WAV Task.Run(async() => { try { // Convert to WAV and resample IMediaInfo prefixInputFile = await FFmpeg.GetMediaInfo(sourceFile); IAudioStream prefixAudioStream = prefixInputFile.AudioStreams.First() .SetCodec(AudioCodec.pcm_f32le) .SetChannels(2) .SetSampleRate(samplingRate); IConversionResult prefixConversionResult = await FFmpeg.Conversions.New() .AddStream(prefixAudioStream) .SetOutput(prefixTmpWavFile) .Start(); } catch (Exception e) { FFmpegErrorTextPrefix = e.Message; throw new Exception("FFmepg error " + e.Message + "\n"); } isReadyPrefix = true; }); while (!isReadyPrefix) { Thread.Sleep(200); if (FFmpegErrorTextPrefix != "") { throw new Exception("FFmepg error: " + FFmpegErrorTextPrefix + "\n"); } } // Read WAV file byte[] prefixWavBytes = File.ReadAllBytes(prefixTmpWavFile); prefixResampled.Write(prefixWavBytes, 0, prefixWavBytes.Length); prefixResampled.Seek(0, SeekOrigin.Begin); // Skip WAV header byte[] bytes = new byte[4]; prefixResampled.Seek(16, 0); prefixResampled.Read(bytes, 0, 4); int Subchunk1Size = BitConverter.ToInt32(bytes, 0); // Get FMT size // Skip some header information prefixResampled.Read(buffer, 0, Subchunk1Size + 12); // Data starts at FMT size + 12 bytes // Read data chunk prefixResampled.Read(bytes, 0, 4); var str = System.Text.Encoding.Default.GetString(bytes); if (str != "data") { throw new Exception("WAV error: Data section not found \n"); } // Skip data length prefixResampled.Read(bytes, 0, 4); } else { var prefixStream = new Mp3FileReader(prefixFile); var prefixResampledTmp = new MediaFoundationResampler(prefixStream, outFormat); // Convert NAudioStream to System.IO.Stream byte[] sampleByte = { 0 }; int read; while ((read = prefixResampledTmp.Read(sampleByte, 0, sampleByte.Length)) > 0) { prefixResampled.Write(sampleByte, 0, read); } prefixResampled.Seek(0, SeekOrigin.Begin); } while (true) { bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { sampleBuffer = MemoryMarshal.Cast <byte, float>(buffer.AsSpan()).ToArray(); } else { sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); } if ((outputData.Length + 0x1000 + sampleBuffer.Length) >= maxSize) { break; } oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { File.Delete(prefixTmpWavFile); } } catch (Exception ex) { throw new Exception("Failed processing prefix file '" + prefixFile + "'"); } } Stream streamResampled = new MemoryStream(); // Linux string tmpWavFile = ""; /* then the real audio file */ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { tmpWavFile = Path.ChangeExtension(Path.GetTempFileName(), "wav"); //Console.Write(" Convert file " + sourceFile + " to WAV. Temp file " + TmpWavFile); // The isReady flag and error test variables are not a nice solution but is working bool isReady = false; String FFmpegErrorText = ""; // Convert to WAV and resample Task.Run(async() => { try { IMediaInfo inputFile = await FFmpeg.GetMediaInfo(sourceFile); IAudioStream audioStream = inputFile.AudioStreams.First() .SetCodec(AudioCodec.pcm_f32le) .SetChannels(2) .SetSampleRate(samplingRate); IConversionResult conversionResult = await FFmpeg.Conversions.New() .AddStream(audioStream) .SetOutput(tmpWavFile) .AddParameter("-map_metadata -1 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact") // Remove meta data .Start(); } catch (Exception e) { FFmpegErrorText = e.Message; Console.WriteLine(e.Message); throw new Exception("FFmepg error " + e.Message + "\n"); } isReady = true; }); while (!isReady) { Thread.Sleep(200); if (FFmpegErrorText != "") { throw new Exception("FFmepg error: " + FFmpegErrorText + "\n"); } } // Read WAV file byte[] wavBytes = File.ReadAllBytes(tmpWavFile); streamResampled.Write(wavBytes, 0, wavBytes.Length); streamResampled.Seek(0, SeekOrigin.Begin); // Skip WAV header byte[] bytes = new byte[4]; streamResampled.Seek(16, 0); streamResampled.Read(bytes, 0, 4); int Subchunk1Size = BitConverter.ToInt32(bytes, 0); // Get FMT size // Skip some header information streamResampled.Read(buffer, 0, Subchunk1Size + 12); // Data starts at FMT size + 12 bytes // Read data chunk streamResampled.Read(bytes, 0, 4); var str = System.Text.Encoding.Default.GetString(bytes); if (str != "data") { throw new Exception("WAV error: Data section not found \n"); } // Skip data length streamResampled.Read(bytes, 0, 4); } else { var stream = new Mp3FileReader(sourceFile); var streamResampledTmp = new MediaFoundationResampler(stream, outFormat); // Convert NAudioStream to System.IO.Stream byte[] sampleByte = { 0 }; int read; while ((read = streamResampledTmp.Read(sampleByte, 0, sampleByte.Length)) > 0) { streamResampled.Write(sampleByte, 0, read); } streamResampled.Seek(0, SeekOrigin.Begin); } while (true) { bytesReturned = streamResampled.Read(buffer, 0, buffer.Length); if (bytesReturned <= 0) { break; } totalBytesRead += bytesReturned; float progress = (float)streamResampled.Position / streamResampled.Length; if ((int)(progress * 20) != lastPct) { lastPct = (int)(progress * 20); if (lastPct % 5 == 0) { if (lastPct != 20) { Console.Write("" + (lastPct * 5) + "%"); } } else { Console.Write("."); } } bool isEmpty = (buffer.Where(v => v != 0).Count() == 0); if (!isEmpty) { float[] sampleBuffer; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { sampleBuffer = MemoryMarshal.Cast <byte, float>(buffer.AsSpan()).ToArray(); } else { sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels); } oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length); } lastIndex = (uint)oggOut.PageCounter; } Console.WriteLine("]"); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { File.Delete(tmpWavFile); } streamResampled.Close(); } catch (OpusOggWriteStream.PaddingException e) { Console.WriteLine(); throw new EncodingException("Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps"); } catch (FileNotFoundException e) { Console.WriteLine(); throw new FileNotFoundException(e.Message); } catch (InvalidDataException e) { Console.WriteLine(); throw new Exception("Failed processing " + sourceFile); } catch (Exception e) { Console.WriteLine(); throw new Exception("Failed processing " + sourceFile + "\n Error: " + e.Message + "\n"); } if (!warned && outputData.Length >= maxSize / 2) { Console.WriteLine("Warning: Approaching 2 GiB, please reduce the bitrate"); warned = true; } } oggOut.Finish(); Header.AudioId = oggOut.LogicalStreamId; } Audio = File.ReadAllBytes(tempName); var prov = new SHA1CryptoServiceProvider(); Header.Hash = prov.ComputeHash(Audio); Header.AudioChapters = chapters.ToArray(); Header.AudioLength = Audio.Length; Header.Padding = new byte[0]; File.Delete(tempName); }