private static void DecodeAudio(string filename) { FFmpegReader reader = new FFmpegReader(filename, Type.Audio); Console.WriteLine("length {0}, frame_size {1}, sample_rate {2}, sample_size {3}, channels {4}", reader.AudioOutputConfig.length, reader.AudioOutputConfig.frame_size, reader.AudioOutputConfig.format.sample_rate, reader.AudioOutputConfig.format.sample_size, reader.AudioOutputConfig.format.channels); int sampleBlockSize = reader.AudioOutputConfig.format.channels * reader.AudioOutputConfig.format.sample_size; int output_buffer_size = reader.AudioOutputConfig.frame_size * reader.AudioOutputConfig.format.channels * reader.AudioOutputConfig.format.sample_size; byte[] output_buffer = new byte[output_buffer_size]; int samplesRead; long timestamp; Type type; MemoryStream ms = new MemoryStream(); // read full stream while ((samplesRead = reader.ReadFrame(out timestamp, output_buffer, output_buffer_size, out type)) > 0) { Console.WriteLine("read " + samplesRead + " @ " + timestamp); // read samples into memory int bytesRead = samplesRead * sampleBlockSize; ms.Write(output_buffer, 0, bytesRead); } // seek back to start reader.Seek(0, Type.Audio); // read again (output should be the same as above) while ((samplesRead = reader.ReadFrame(out timestamp, output_buffer, output_buffer_size, out type)) > 0) { Console.WriteLine("read " + samplesRead + " @ " + timestamp); } reader.Dispose(); // write memory to wav file ms.Position = 0; MemorySourceStream mss = new MemorySourceStream(ms, 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)); IeeeStream ieee = new IeeeStream(mss); NAudioSinkStream nAudioSink = new NAudioSinkStream(ieee); WaveFileWriter.CreateWaveFile(filename + ".ffmpeg.wav", nAudioSink); }
private static void DecodeVideo(string filename, int videoFrameInterval) { FFmpegReader reader = new FFmpegReader(filename, Type.Video); Console.WriteLine("length {0}, frame_size {1}x{2}, frame_rate {3}, aspect_ratio {4}", reader.VideoOutputConfig.length, reader.VideoOutputConfig.format.width, reader.VideoOutputConfig.format.height, reader.VideoOutputConfig.format.frame_rate, reader.VideoOutputConfig.format.aspect_ratio); int output_buffer_size = reader.VideoOutputConfig.format.width * reader.VideoOutputConfig.format.height * 3 /* RGB */; byte[] output_buffer = new byte[output_buffer_size]; int frameRead; long timestamp; Type type; int frameCount = 0; Bitmap rgbFrame = new Bitmap(reader.VideoOutputConfig.format.width, reader.VideoOutputConfig.format.height); // read full stream while ((frameRead = reader.ReadFrame(out timestamp, output_buffer, output_buffer_size, out type)) > 0) { Console.WriteLine("read frame " + frameCount + " @ " + timestamp); if (frameCount % videoFrameInterval == 0) { BitmapData rgbFrameData = rgbFrame.LockBits(new Rectangle(0, 0, rgbFrame.Width, rgbFrame.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); Marshal.Copy(output_buffer, 0, rgbFrameData.Scan0, output_buffer_size); rgbFrame.UnlockBits(rgbFrameData); rgbFrame.Save(String.Format("{0}.{1:00000000}.png", filename, frameCount), ImageFormat.Png); } frameCount++; } reader.Dispose(); }
/// <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); // workaround to get NAudio WaveFormat (instead of creating it manually here) var mss = new MemorySourceStream(null, 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)); var nass = new NAudioSinkStream(mss); var waveFormat = nass.WaveFormat; var writer = new WaveFileWriter(outputFileInfo.FullName, waveFormat); int output_buffer_size = reader.AudioOutputConfig.frame_size * mss.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 * mss.SampleBlockSize; writer.Write(output_buffer, 0, bytesRead); } reader.Dispose(); writer.Close(); return(outputFileInfo); }