/// <summary>Add an existing wave audio stream to the file</summary> /// <param name="waveData">The new stream's data</param> /// <param name="streamInfo">Header info for the new stream</param> /// <param name="streamFormat">The new stream' format info</param> /// <param name="streamLength">Length of the new stream</param> public void AddAudioStream(IntPtr waveData, Avi.AVISTREAMINFO streamInfo, Avi.PCMWAVEFORMAT streamFormat, int streamLength) { IntPtr aviStream; int result = Avi.AVIFileCreateStream(aviFile, out aviStream, ref streamInfo); if (result != 0) { throw new Exception("Exception in AVIFileCreateStream: " + result.ToString()); } result = Avi.AVIStreamSetFormat(aviStream, 0, ref streamFormat, Marshal.SizeOf(streamFormat)); if (result != 0) { throw new Exception("Exception in AVIStreamSetFormat: " + result.ToString()); } result = Avi.AVIStreamWrite(aviStream, 0, streamLength, waveData, streamLength, Avi.AVIIF_KEYFRAME, 0, 0); if (result != 0) { throw new Exception("Exception in AVIStreamWrite: " + result.ToString()); } result = Avi.AVIStreamRelease(aviStream); if (result != 0) { throw new Exception("Exception in AVIStreamRelease: " + result.ToString()); } }
/// <summary>Apply a format to a new stream</summary> /// <param name="aviStream">The IAVISTREAM</param> /// <remarks> /// The format must be set before the first frame can be written, /// and it cannot be changed later. /// </remarks> private void SetFormat(IntPtr aviStream, int writePosition) { Avi.BITMAPINFO bi = new Avi.BITMAPINFO(); bi.bmiHeader.biWidth = width; bi.bmiHeader.biHeight = height; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = countBitsPerPixel; bi.bmiHeader.biSizeImage = frameSize; bi.bmiHeader.biSize = Marshal.SizeOf(bi.bmiHeader); if (countBitsPerPixel < 24) { bi.bmiHeader.biClrUsed = this.palette.Length; bi.bmiHeader.biClrImportant = this.palette.Length; bi.bmiColors = new Avi.RGBQUAD[this.palette.Length]; this.palette.CopyTo(bi.bmiColors, 0); bi.bmiHeader.biSize += bi.bmiColors.Length * Avi.RGBQUAD_SIZE; } int result = Avi.AVIStreamSetFormat(aviStream, writePosition, ref bi, bi.bmiHeader.biSize); if (result != 0) { throw new Exception("Error in VideoStreamSetFormat: " + result.ToString("X")); } }
/// <summary>Add an existing wave audio stream to the file</summary> /// <param name="newStream">The stream to add</param> /// <param name="startAtFrameIndex"> /// The index of the video frame at which the sound is going to start. /// '0' inserts the sound at the beginning of the video. /// </param> public void AddAudioStream(AudioStream newStream, int startAtFrameIndex) { Avi.AVISTREAMINFO streamInfo = new Avi.AVISTREAMINFO(); Avi.PCMWAVEFORMAT streamFormat = new Avi.PCMWAVEFORMAT(); int streamLength = 0; IntPtr rawData = newStream.GetStreamData(ref streamInfo, ref streamFormat, ref streamLength); IntPtr waveData = rawData; if (startAtFrameIndex > 0) { //not supported //streamInfo.dwStart = startAtFrameIndex; double framesPerSecond = GetVideoStream().FrameRate; double samplesPerSecond = newStream.CountSamplesPerSecond; double startAtSecond = startAtFrameIndex / framesPerSecond; int startAtSample = (int)(samplesPerSecond * startAtSecond); waveData = InsertSilence(startAtSample - 1, waveData, streamLength, ref streamInfo); } IntPtr aviStream; int result = Avi.AVIFileCreateStream(aviFile, out aviStream, ref streamInfo); if (result != 0) { throw new Exception("Exception in AVIFileCreateStream: " + result.ToString()); } result = Avi.AVIStreamSetFormat(aviStream, 0, ref streamFormat, Marshal.SizeOf(streamFormat)); if (result != 0) { throw new Exception("Exception in AVIStreamSetFormat: " + result.ToString()); } result = Avi.AVIStreamWrite(aviStream, 0, streamLength, waveData, streamLength, Avi.AVIIF_KEYFRAME, 0, 0); if (result != 0) { throw new Exception("Exception in AVIStreamWrite: " + result.ToString()); } result = Avi.AVIStreamRelease(aviStream); if (result != 0) { throw new Exception("Exception in AVIStreamRelease: " + result.ToString()); } Marshal.FreeHGlobal(waveData); }