|
質問者のひろしです。
DirectShowを使ってデスクトップのレコーディングする方法が解決できなかった為 他の方法で対応することにしました。
http://www.adp-gmbh.ch/csharp/avi/write_avi.html
上記ののページを参考にデスクトップのレコーディングする部分は何とか出来ました。 音声の録音についてはDirectShowを使って、映像とは別々のファイル(avi)に出力し、
http://homepage1.nifty.com/nekora/soft/howto/avi.html
上記のページを参考にして、映像と音声を合成すると言う方法で解決しました。
しかし、またどうしても解決できない問題にぶつかってしまいました。 デスクトップの映像を録画する際に、何故か上下が反転してしまうのです。 原因をご存知の方、ご教授よろしくお願いいたします。
(最悪、bitmap を回転させて AddFram 関数を呼ぶことも考えています・・・)
private void CreateStream() { AVISTREAMINFOW strhdr = new AVISTREAMINFOW(); strhdr.fccType = streamtypeVIDEO; strhdr.fccHandler = _fccHandler_MP4V2; strhdr.dwFlags = 0; strhdr.dwCaps = 0; strhdr.wPriority = 0; strhdr.wLanguage = 0; strhdr.dwScale = 1; strhdr.dwRate = _frameRate; // Frames per Second strhdr.dwStart = 0; strhdr.dwLength = 0; strhdr.dwInitialFrames = 0; strhdr.dwSuggestedBufferSize = (uint)(_stride * _height); strhdr.dwQuality = 0xffffffff; //-1; // Use default strhdr.dwSampleSize = 0; strhdr.rect_top = 0; strhdr.rect_left = 0; strhdr.rect_bottom = _height; strhdr.rect_right = _width; strhdr.dwEditCount = 0; strhdr.dwFormatChangeCount = 0; strhdr.szName0 = 0; strhdr.szName1 = 0; int hr = AVIFileCreateStream(_pFile, out _pStream, ref strhdr);
if (hr != 0) { throw new AviException("AVIFileCreateStream"); } }
unsafe private void SetOptions() { int hr = 0;
AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); opts.fccType = 0; //fccType_; opts.fccHandler = _fccHandler_MP4V2; //fccHandler_; opts.dwKeyFrameEvery = 0; opts.dwQuality = 7500; // 0 .. 10000 opts.dwFlags = 8; // AVICOMRPESSF_KEYFRAMES = 4 opts.dwBytesPerSecond = 0; opts.lpFormat = IntPtr.Zero; opts.cbFormat = 0; opts.lpParms = new IntPtr(5611280); // IntPtr.Zero; opts.cbParms = 120; opts.dwInterleaveEvery = 0;
// 圧縮方法選択ダイアログを表示する場合は以下のコメントをはずす //AVICOMPRESSOPTIONS* p = &opts; //AVICOMPRESSOPTIONS** pp = &p; //IntPtr x = _pStream; //IntPtr* ptr_ps = &x; //AVISaveOptions(0, 0, 1, ptr_ps, pp); //
// TODO: AVISaveOptionsFree(...)
hr = AVIMakeCompressedStream(out _psCompressed, _pStream, ref opts, 0); if (hr != 0) { throw new AviException("AVIMakeCompressedStream"); }
BITMAPINFOHEADER bi = new BITMAPINFOHEADER(); bi.biSize = 40; bi.biWidth = (Int32)_width; bi.biHeight = (Int32)_height; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; // 0 = BI_RGB bi.biSizeImage = (uint)(_stride * _height); bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0;
hr = AVIStreamSetFormat(_psCompressed, 0, ref bi, 40); if (hr != 0) { throw new AviException("AVIStreamSetFormat", hr); } }
public Bitmap Open(string fileName, UInt32 frameRate, int width, int height) { _rect = new Rectangle(0, 0, width, height); _frameRate = frameRate; _width = (UInt32)width; _height = (UInt32)height;
_bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); BitmapData bmpDat = _bmp.LockBits(_rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); _stride = bmpDat.Stride; _bmp.UnlockBits(bmpDat);
AVIFileInit(); int hr = AVIFileOpenW(ref _pFile, fileName, 4097 /* OF_WRITE | OF_CREATE (winbase.h) */, 0); if (hr != 0) { throw new AviException("error for AVIFileOpenW"); }
CreateStream();
SetOptions();
return _bmp; }
public void AddFrame() {
BitmapData bmpDat = _bmp.LockBits(_rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int hr = AVIStreamWrite( _psCompressed, _count, 1, bmpDat.Scan0, (int)(_stride * _height), 0, 0, 0); //_pStream, _count, 1, bmpDat.Scan0, (int)(_stride * _height), 0, 0, 0); if (hr != 0) { throw new AviException("AVIStreamWrite"); }
_bmp.UnlockBits(bmpDat);
_count++; }
|