private void bw_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; Parameters parameters = (Parameters)e.Argument; var streams = parameters.SourceFiles.Select(fi => AudioStreamFactory.FromFileInfo(fi)); // load source stream var sourceStream = new ConcatenationStream(streams.ToArray()); var firstFile = parameters.SourceFiles.First(); string targetFileNamePrefix = firstFile.FullName.Remove(firstFile.FullName.Length - firstFile.Extension.Length); string targetFileNameSuffix = firstFile.Extension; int partCount = 0; Random random = new Random(); CropStream cropStream = new CropStream(sourceStream, 0, 0); while (sourceStream.Position < sourceStream.Length) { partCount++; int length = random.Next(parameters.MinLength, parameters.MaxLength); // length in seconds of the current part to write long byteLength = TimeUtil.TimeSpanToBytes(new TimeSpan(TimeUtil.SECS_TO_TICKS * length), cropStream.Properties); Debug.WriteLine("writing part " + partCount + " (" + length + " secs = " + byteLength + " bytes)"); Debug.WriteLine("before: " + cropStream.Begin + " / " + cropStream.End + " / " + cropStream.Position + " / " + sourceStream.Position); cropStream.Begin = cropStream.End; cropStream.End += sourceStream.Length - cropStream.Begin < byteLength ? sourceStream.Length - cropStream.Begin : byteLength; cropStream.Position = 0; Debug.WriteLine("after : " + cropStream.Begin + " / " + cropStream.End + " / " + cropStream.Position + " / " + sourceStream.Position); AudioStreamFactory.WriteToFile(cropStream, String.Format("{0}.part{1:000}{2}", targetFileNamePrefix, partCount, targetFileNameSuffix)); if (worker.CancellationPending) { e.Cancel = true; Debug.WriteLine("canceled"); return; } worker.ReportProgress((int)((double)sourceStream.Position / sourceStream.Length * 100)); } Debug.WriteLine("finished"); }
static void Process(Dictionary <string, double> mapping, DirectoryInfo indir, DirectoryInfo outdir) { Dictionary <FileInfo, double> fileMapping = new Dictionary <FileInfo, double>(); foreach (string fileNamePattern in mapping.Keys) { double factor = mapping[fileNamePattern]; foreach (FileInfo fileInfo in indir.EnumerateFiles(fileNamePattern)) { fileMapping.Add(fileInfo, factor); } } Parallel.ForEach <FileInfo>(fileMapping.Keys, (fileInfo) => { double factor = fileMapping[fileInfo]; FileInfo outputFileInfo = new FileInfo(Path.Combine(outdir.FullName, fileInfo.Name)); if (outputFileInfo.Exists) { Console.WriteLine(fileInfo.Name + " SKIP (file already existing)"); return; } Console.WriteLine(fileInfo.Name); try { IAudioStream inputStream = AudioStreamFactory.FromFileInfoIeee32(fileInfo); IAudioStream resamplingStream = new ResamplingStream(inputStream, ResamplingQuality.VeryHigh, factor); MixerStream sampleRateResetStream = new MixerStream(resamplingStream.Properties.Channels, inputStream.Properties.SampleRate); sampleRateResetStream.Add(resamplingStream); IAudioStream outputStream = sampleRateResetStream; AudioStreamFactory.WriteToFile(outputStream, outputFileInfo.FullName); } catch (Exception e) { Console.WriteLine("Error processing " + fileInfo.Name + ": " + e.Message); } }); }
/// <summary> /// Creates a Wave format proxy file in the same directory and with the same name as the specified file, /// if no storage directory is specified (i.e. if it is null). If a storage directory is specified, the proxy /// file will be stored in the specified directory with a hashed file name to avoid name collisions and /// file overwrites. The story directory option is convenient for the usage of temporary or working directories. /// </summary> /// <param name="fileInfo">the file for which a proxy file should be created</param> /// <param name="storageDirectory">optional directory where the proxy file will be stored, can be null</param> /// <returns>the FileInfo of the proxy file</returns> public static FileInfo CreateWaveProxy(FileInfo fileInfo, DirectoryInfo storageDirectory) { FileInfo outputFileInfo; if (storageDirectory == null) { // Without a storage directory, store the proxy file beside the original file outputFileInfo = new FileInfo(fileInfo.FullName + ".ffproxy.wav"); } else { // With a storage directory specified, store the proxy file with a hashed name // (to avoid name collision / overwrites) in the target directory (e.g. a temp or working directory) using (var sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.Unicode.GetBytes(fileInfo.FullName)); string hashString = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); outputFileInfo = new FileInfo(Path.Combine(storageDirectory.FullName, hashString + ".ffproxy.wav")); } } if (outputFileInfo.Exists) { Console.WriteLine("Proxy already existing, using " + outputFileInfo.Name); return(outputFileInfo); } var reader = new FFmpegReader(fileInfo, FFmpeg.Type.Audio); var writer = new MemoryWriterStream(new AudioProperties( reader.AudioOutputConfig.format.channels, reader.AudioOutputConfig.format.sample_rate, reader.AudioOutputConfig.format.sample_size * 8, reader.AudioOutputConfig.format.sample_size == 4 ? AudioFormat.IEEE : AudioFormat.LPCM)); int output_buffer_size = reader.AudioOutputConfig.frame_size * writer.SampleBlockSize; byte[] output_buffer = new byte[output_buffer_size]; int samplesRead; long timestamp; FFmpeg.Type type; // sequentially read samples from decoder and write it to wav file while ((samplesRead = reader.ReadFrame(out timestamp, output_buffer, output_buffer_size, out type)) > 0) { int bytesRead = samplesRead * writer.SampleBlockSize; writer.Write(output_buffer, 0, bytesRead); } reader.Dispose(); writer.Position = 0; AudioStreamFactory.WriteToFile(writer, outputFileInfo.FullName); writer.Close(); return(outputFileInfo); }