2010-04-06 2 views
3

내 사이트에 나열된 비디오의 축소판을 표시하고 싶습니다. 특정 시간의 비디오에서 하나의 프레임을 가져 와서 축소판으로 표시하려고합니다.WMV 비디오의 축소판을 만드는 방법

.Net을 사용하면 가능합니까? (C# 또는 VB)

답변

2

예 가능합니다. DirectShow.NET을 사용해야합니다. 유용하다고 this 발견했습니다.

편집 :

OK 내가 그것을 사용하기 때문에 라이브러리가 변경되었습니다 ... 저주 오픈 소스 :

난 그냥 다음 코드로 변환하고 테스트하고 (나를 위해 잘 작동처럼 보인다 그것은 C에서 WMV가 있다고 가정합니다 : \가 C4.wmv라는 AAA 및 출력이 C로 이동합니다 :

IGraphBuilder graphbuilder = (IGraphBuilder)new FilterGraph(); 
     ISampleGrabber samplegrabber = (ISampleGrabber) new SampleGrabber(); 
     graphbuilder.AddFilter((IBaseFilter)samplegrabber, "samplegrabber"); 

     AMMediaType mt = new AMMediaType(); 
     mt.majorType = MediaType.Video; 
     mt.subType = MediaSubType.RGB24; 
     mt.formatType = FormatType.VideoInfo; 
     samplegrabber.SetMediaType(mt); 

     int hr = graphbuilder.RenderFile("C:\\aaa\\c4.wmv", null); 

     IMediaEventEx mediaEvt = (IMediaEventEx)graphbuilder; 
     IMediaSeeking mediaSeek = (IMediaSeeking)graphbuilder; 
     IMediaControl mediaCtrl = (IMediaControl)graphbuilder; 
     IBasicAudio basicAudio = (IBasicAudio)graphbuilder; 
     IVideoWindow videoWin = (IVideoWindow)graphbuilder; 

     basicAudio.put_Volume(-10000); 
     videoWin.put_AutoShow(OABool.False); 

     samplegrabber.SetOneShot(true); 
     samplegrabber.SetBufferSamples(true); 

     long d = 0; 
     mediaSeek.GetDuration(out d); 
     long numSecs = d/10000000; 

     long secondstocapture = (long)(numSecs * 0.10f); 


     DsLong rtStart, rtStop; 
     rtStart = new DsLong(secondstocapture * 10000000); 
     rtStop = rtStart; 
     mediaSeek.SetPositions(rtStart, AMSeekingSeekingFlags.AbsolutePositioning, rtStop, AMSeekingSeekingFlags.AbsolutePositioning); 

     mediaCtrl.Run(); 
     EventCode evcode; 
     mediaEvt.WaitForCompletion(-1, out evcode); 

     VideoInfoHeader videoheader = new VideoInfoHeader(); 
     AMMediaType grab = new AMMediaType(); 
     samplegrabber.GetConnectedMediaType(grab); 
     videoheader = 
     (VideoInfoHeader)Marshal.PtrToStructure(grab.formatPtr, 
     typeof(VideoInfoHeader)); 


     int width = videoheader.SrcRect.right; 
     int height = videoheader.SrcRect.bottom; 
     Bitmap b = new Bitmap(width, height, PixelFormat.Format24bppRgb); 

     uint bytesPerPixel = (uint)(24 >> 3); 
     uint extraBytes = ((uint)width * bytesPerPixel) % 4; 
     uint adjustedLineSize = bytesPerPixel * ((uint)width + extraBytes); 
     uint sizeOfImageData = (uint)(height) * adjustedLineSize; 


     BitmapData bd1 = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
     int bufsize = (int)sizeOfImageData; 
     int n = samplegrabber.GetCurrentBuffer(ref bufsize, bd1.Scan0); 
     b.UnlockBits(bd1); 
     b.RotateFlip(RotateFlipType.RotateNoneFlipY); 
     b.Save("C:\\aaa\\out.bmp"); 
     Marshal.ReleaseComObject(graphbuilder); 
     Marshal.ReleaseComObject(samplegrabber); 

는 또한 다이렉트가있는 프레임 워크의 somethign입니다 점에 유의) \ AAA \ out.bmp limbo ... MS 종류는 당신이 Media Foundation에가는 것이 좋습니다 ... 저는 오래된 학교 DirectX입니다. 솔직히 더 이상 그렇게하지 않는 프로그래머.

+0

안녕하세요, 는 내가 DirectShowLib-2005.dll을 참조,하지만 난 유형 comtype = Type.GetTypeFromCLSID (Clsid.FilterGraph를) :)에 당신이 나를 링크 된 예제 코드의 라인 2에 붙어입니다; ClsId는 무엇입니까? – Michel

+0

예! 그것은 작동합니다. 매우 감사합니다! – Michel

+0

글쎄, 음, 나는 거의 감히 묻지 않는다. 나는 카메라와 함께 제공되는 소프트웨어를 업데이트했다. GRMBL 소프트웨어는 이제 WMV로 내보낼 수 없지만, 네이티브 형식 인 MP4로만 내보낼 수있다. MP4 파일에서도 작동하도록 코드를 이해하려고 시도했지만 (MP4 파일에서 충돌하기 때문에) 실제로 어떻게 작동하는지 모릅니다. 도와 주실 수 있습니까? – Michel

관련 문제