Как создавать миниатюры из видео WMV

я хочу отображать миниатюры для видео, перечисленных на моем сайте, я хочу получить один кадр из видео (из определенного времени) и отобразить их в виде миниатюр.

Возможно ли это с помощью .Net? (С# или VB)


person Michel    schedule 06.04.2010    source источник


Ответы (1)


Да, это возможно. Вам нужно использовать DirectShow.NET. Я нашел это полезным.

РЕДАКТИРОВАТЬ :

Хорошо, похоже, что библиотека изменилась с тех пор, как я ее использовал... проклятие с открытым исходным кодом :)

Я только что перевел следующий код и проверил, и он отлично работает для меня (обратите внимание, что предполагается, что в c:\aaa есть wmv с именем C4.wmv, и вывод будет идти в c:\aaa\out.bmp)

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);

Также имейте в виду, что DirectShow является чем-то вроде фреймворка в подвешенном состоянии... MS как бы рекомендует вам обратиться в Media Foundation... Я программист старой школы DirectX, который, честно говоря, больше ничего с ним не делает.

person Gray Area    schedule 06.04.2010
comment
Привет, я сослался на DirectShowLib-2005.dll, но застрял на строке 2 примера кода, на который вы меня ссылали :) Type comtype = Type.GetTypeFromCLSID(Clsid.FilterGraph); Каким будет ClsId? - person Michel; 06.04.2010
comment
Ну, хм, вряд ли осмелюсь спросить... я обновил программное обеспечение, которое идет с моей камерой, и программное обеспечение GRMBL теперь не позволяет мне экспортировать в WMV, а только в его родной формат: MP4. Я пытался понять код, чтобы заставить его работать и с файлом MP4 (потому что он падает в файле MP4), но я действительно не знаю, как это сделать. Можете ли вы также помочь мне с этим? - person Michel; 10.04.2010
comment
Боюсь, у меня нет такого большого опыта работы с MPEG-4 и DS. Я знаю (последнее, что я слышал), что DS не поддерживает MPEG-4 из коробки, и вам нужно получить сторонний фильтр (быстрый поиск в Google находит это softpedia.com/progDownload/ Но я не пользовался.). Большая часть моего опыта работы с MPEG-4 связана с хакингом ffmpeg для создания транскодеров. Я бы посоветовал вам взглянуть на ffmpeg как на решение для удержания команды, которое вы можете использовать для создания миниатюр на стороне сервера (я очень успешно использовал это на некоторых очень больших видеосайтах). - person Gray Area; 12.04.2010