Najszybsza metoda przechwytywania ekranu w systemie Windows

159

Chcę napisać program do wyświetlania ekranu dla platformy Windows, ale nie jestem pewien, jak zrobić zrzut ekranu. Jedyną metodą, o której wiem, jest użycie GDI, ale jestem ciekawy, czy istnieją inne sposoby, aby to zrobić, a jeśli tak, to który generuje najmniejsze koszty? Szybkość jest priorytetem.

Program do wyświetlania ekranu będzie służył do nagrywania materiału z gry, chociaż jeśli to zawęzi opcje, nadal jestem otwarty na wszelkie inne sugestie, które wykraczają poza ten zakres. W końcu wiedza nie jest zła.

Edycja : natknąłem się na ten artykuł: Różne metody przechwytywania ekranu . Wprowadził mnie w sposób robienia tego w Windows Media API i DirectX. We wniosku wspomniano, że wyłączenie akceleracji sprzętowej może drastycznie poprawić wydajność aplikacji przechwytującej. Ciekaw jestem, dlaczego tak jest. Czy ktoś mógłby wypełnić dla mnie brakujące pola?

Edycja : Czytałem, że programy do wyświetlania ekranu, takie jak Camtasia, używają własnego sterownika przechwytywania. Czy ktoś mógłby mi szczegółowo wyjaśnić, jak to działa i dlaczego jest szybsze? Mogę też potrzebować wskazówek dotyczących implementacji czegoś takiego, ale jestem pewien, że i tak istnieje dokumentacja.

Poza tym wiem teraz, jak FRAPS nagrywa ekran. Przechwytuje podstawowy interfejs API grafiki w celu odczytu z bufora tylnego. Z tego, co rozumiem, jest to szybsze niż odczyt z przedniego bufora, ponieważ czytasz z systemowej pamięci RAM, a nie z pamięci RAM wideo. Możesz przeczytać artykuł tutaj .

jakiś facet
źródło
Czy zastanawiałeś się, zamiast graficznie rejestrować zawartość ekranu, używając systemu powtórek ?
Benjamin Lindley,
2
Nie musisz niczego zaczepiać. Musisz tylko napisać zdarzenia wejściowe, aby nie sterowały bezpośrednio grą, ale zamiast tego wywoływały inne funkcje. Na przykład, jeśli gracz naciska lewy klawisz, nie zmniejszasz po prostu pozycji gracza x. Zamiast tego wywołujesz funkcję, taką jak MovePlayerLeft(). Ponadto rejestrujesz czas i czas trwania naciśnięć klawiszy i innych danych wejściowych. Następnie, gdy jesteś w trybie odtwarzania, po prostu ignorujesz dane wejściowe i zamiast tego odczytujesz zapisane dane. Jeśli w danych widać naciśnięcie lewego klawisza, dzwonisz MovePlayerLeft().
Benjamin Lindley,
1
@PigBen To będzie ogólna aplikacja do nagrywania materiału z gry. Nie jest przeznaczony do konkretnej gry. Z tego, co wiem, ktoś naciśnie lewy klawisz może oznaczać ruch w prawo. Ponadto nie wziąłeś pod uwagę wydarzeń, na które użytkownik nie ma wpływu. - A co z renderowaniem?
someguy,
1
@someguy Ok, myślę, że robisz coś znacznie bardziej intensywnego. Dodałem procedurę wykorzystującą powyższe metody, aby zaoszczędzić na odtwarzaniu plików AVI w grze przy około 30 klatkach na sekundę bez żadnych problemów. Zrobiłem wielomonitorowy rejestrator ekranowy przy użyciu Windows API do "optymalizacji siły roboczej", ale działał źle nawet przy docelowych 4 klatkach na sekundę.
AJG85,
1
W witrynie repozytorium UltraVNC znajduje się sterownik lustrzany typu open source dla systemu Windows tutaj ultravnc.svn.sourceforge.net/viewvc/ultravnc/ ...
Beached

Odpowiedzi:

62

To jest to, czego używam do zbierania pojedynczych ramek, ale jeśli zmodyfikujesz to i pozostawisz oba cele otwarte przez cały czas, możesz „przesłać” to na dysk używając statycznego licznika dla nazwy pliku. - Nie pamiętam, gdzie to znalazłem, ale dzięki komukolwiek zostało to zmodyfikowane!

void dump_buffer()
{
   IDirect3DSurface9* pRenderTarget=NULL;
   IDirect3DSurface9* pDestTarget=NULL;
     const char file[] = "Pickture.bmp";
   // sanity checks.
   if (Device == NULL)
      return;

   // get the render target surface.
   HRESULT hr = Device->GetRenderTarget(0, &pRenderTarget);
   // get the current adapter display mode.
   //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);

   // create a destination surface.
   hr = Device->CreateOffscreenPlainSurface(DisplayMde.Width,
                         DisplayMde.Height,
                         DisplayMde.Format,
                         D3DPOOL_SYSTEMMEM,
                         &pDestTarget,
                         NULL);
   //copy the render target to the destination surface.
   hr = Device->GetRenderTargetData(pRenderTarget, pDestTarget);
   //save its contents to a bitmap file.
   hr = D3DXSaveSurfaceToFile(file,
                              D3DXIFF_BMP,
                              pDestTarget,
                              NULL,
                              NULL);

   // clean up.
   pRenderTarget->Release();
   pDestTarget->Release();
}
Brandrew
źródło
Dzięki. Jakiś czas temu słyszałem o tej metodzie, o której mówiono, że jest szybsza niż odczyt z przedniego bufora. Czy naprawdę robisz to w ten sposób i czy to działa poprawnie?
someguy
Problem z przednim buforem polega na dostępie, to znaczy próbie skopiowania zwykłego, który aktualnie renderowany "przerywa" kopię. U mnie działa wystarczająco dobrze i zjada mój dysk twardy!
Brandrew
@bobobobo Nie wiem, jak by to dokładnie wyglądało, ale myślałem o użyciu czegoś takiego jak Huffyuv. Edycja: Albo pozwól użytkownikowi wybrać jeden z dostępnych filtrów bezpośredniego pokazu.
someguy,
1
Po prostu nie mogę tego zrobić ... DirectX wypluwa jakieś nieprawidłowe wywołanie w części GetRenderTargetData. Oczywiście sposób, w jaki tworzysz swoje urządzenie, musi mieć duże znaczenie.
LightStriker
12
głos przeciw, działa tylko dla twojej własnej aplikacji, więc nie może być używany do nagrywania programów ogólnych
user3125280
32

EDYCJA: Widzę, że jest to wymienione pod Twoim pierwszym linkiem edycji jako „sposób GDI”. To wciąż przyzwoity sposób, nawet z poradami dotyczącymi wydajności na tej stronie, wydaje mi się, że można łatwo uzyskać 30 klatek na sekundę.

Z tego komentarza (nie mam doświadczenia w tym, odnoszę się tylko do kogoś, kto to robi):

HDC hdc = GetDC(NULL); // get the desktop device context
HDC hDest = CreateCompatibleDC(hdc); // create a device context to use yourself

// get the height and width of the screen
int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);

// create a bitmap
HBITMAP hbDesktop = CreateCompatibleBitmap( hdc, width, height);

// use the previously created device context with the bitmap
SelectObject(hDest, hbDesktop);

// copy from the desktop device context to the bitmap device context
// call this once per 'frame'
BitBlt(hDest, 0,0, width, height, hdc, 0, 0, SRCCOPY);

// after the recording is done, release the desktop context you got..
ReleaseDC(NULL, hdc);

// ..delete the bitmap you were using to capture frames..
DeleteObject(hbDesktop);

// ..and delete the context you created
DeleteDC(hDest);

Nie mówię, że jest to najszybsze, ale BitBltoperacja jest ogólnie bardzo szybka, jeśli kopiujesz między kompatybilnymi kontekstami urządzeń.

Dla porównania, Open Broadcaster Software implementuje coś takiego jako część swojej metody „dc_capture” , chociaż zamiast tworzyć kontekst docelowy hDestza pomocą CreateCompatibleDC, używa znaku IDXGISurface1, który działa z DirectX 10+. Jeśli nie ma dla tego wsparcia, wracają do CreateCompatibleDC.

Aby to zmienić, aby korzystać z aplikacji specyficzne, trzeba zmienić pierwszej linii GetDC(game), gdzie gamejest uchwytem okna gry, a następnie ustawić prawo heighti widthokna w grze zbyt.

Gdy masz piksele w hDest / hbDesktop, nadal musisz zapisać je do pliku, ale jeśli robisz zrzut ekranu, to pomyślałem, że chciałbyś buforować pewną ich liczbę w pamięci i zapisać w pliku wideo fragmentami, więc nie będę wskazywał na kod do zapisywania statycznego obrazu na dysku.


źródło
3
msdn.microsoft.com/en-us/library/dd183370%28VS.85%29.aspx Fragment: Jeśli formaty kolorów w kontekstach urządzenia źródłowego i docelowego nie są zgodne, funkcja BitBlt konwertuje źródłowy format koloru, aby pasował do miejsca docelowego format.
2
Pewne dowody na poparcie tego byłoby dobre. Czy opublikowałeś gdzieś porównanie wydajności lub widziałeś dokładne porównanie?
2
Spróbuj go sprofilować. Jak powiedziałem w poście, odnoszę się do kogoś, kto ma doświadczenie z GDI. Jeśli wycieka pamięć, a wiesz, jak to naprawić, edytuj wpis, aby wyeliminować wyciek.
1
Uzyskałem około 5 fps tą metodą. To było na laptopie ze zintegrowaną grafiką, więc spodziewałbym się lepszego po komputerze stacjonarnym z prawdziwą kartą graficzną, ale nadal jest bardzo wolny.
Timmmm,
1
@Timmmm Dodałem odniesienie do sposobu, w jaki OBS to implementuje. Mam nadzieję, że może to trochę przyspieszyć sprawę.
19

Napisałem oprogramowanie do przechwytywania wideo, podobne do FRAPS dla aplikacji DirectX. Kod źródłowy jest dostępny, a mój artykuł wyjaśnia ogólną technikę. Zajrzyj na http://blog.nektra.com/main/2013/07/23/instrumenting-direct3d-applications-to-capture-video-and-calculate-frames-per-second/

Szanuj Twoje pytania dotyczące wydajności,

  • DirectX powinien być szybszy niż GDI, z wyjątkiem sytuacji, gdy czytasz z przedniego bufora, który jest bardzo wolny. Moje podejście jest podobne do FRAPS (czytanie z bufora wstecznego). Przechwytuję zestaw metod z interfejsów Direct3D.

  • Do nagrywania wideo w czasie rzeczywistym (przy minimalnym wpływie aplikacji) niezbędny jest szybki kodek. FRAPS używa własnego bezstratnego kodeka wideo. Lagarith i HUFFYUV to ogólne bezstratne kodeki wideo przeznaczone do zastosowań w czasie rzeczywistym. Powinieneś spojrzeć na nie, jeśli chcesz wyprowadzić pliki wideo.

  • Innym podejściem do nagrywania screencastów może być napisanie Mirror Driver. Według Wikipedii: gdy dublowanie wideo jest aktywne, za każdym razem, gdy system rysuje do głównego urządzenia wideo w lokalizacji wewnątrz obszaru lustrzanego, kopia operacji rysowania jest wykonywana na lustrzanym urządzeniu wideo w czasie rzeczywistym. Zobacz sterowniki lustrzane w witrynie MSDN: http://msdn.microsoft.com/en-us/library/windows/hardware/ff568315(v=vs.85).aspx .

Hernán
źródło
16

Używam d3d9 do uzyskania bufora wstecznego i zapisuję go do pliku png za pomocą biblioteki d3dx:

    IDirect3DSurface9 * powierzchnia;

    // GetBackBuffer
    idirect3ddevice9-> GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, & surface);

    // zapisz powierzchnię
    D3DXSaveSurfaceToFileA ("nazwa_pliku.png", D3DXIFF_PNG, powierzchnia, NULL, NULL);

    SAFE_RELEASE (powierzchnia);

Aby to zrobić, powinieneś stworzyć swój swapbuffer z

d3dpps.SwapEffect = D3DSWAPEFFECT_COPY ; // for screenshots.

(Więc gwarantujesz, że bufor wsteczny nie zostanie uszkodzony przed zrobieniem zrzutu ekranu).

bobobobo
źródło
To ma sens, dzięki. Czy wiesz, jaka jest różnica między tym a GetRenderTargetjest?
someguy
To po prostu pobiera bieżący cel renderowania (może to być inna powierzchnia poza ekranem, jeśli ktoś renderuje teksturę w momencie wywołania).
bobobobo
13

W moim Impression, podejście GDI i podejście DX mają inny charakter. malowanie za pomocą GDI stosuje metodę FLUSH, podejście FLUSH rysuje ramkę, a następnie ją czyści i przerysowuje kolejną klatkę w tym samym buforze, co spowoduje migotanie w grach wymagających dużej liczby klatek na sekundę.

  1. DLACZEGO DX szybciej? w DX (lub świecie grafiki) stosowana jest bardziej dojrzała metoda zwana renderowaniem podwójnego bufora, w której obecne są dwa bufory, gdy jest obecny bufor przedni do sprzętu, można renderować również do drugiego bufora, a następnie po klatce 1 jest Po zakończeniu renderowania system przełącza się na inny bufor (blokując go na potrzeby prezentacji sprzętowej i zwalniając poprzedni bufor), w ten sposób znacznie poprawia się nieefektywność renderowania.
  2. DLACZEGO szybciej zmniejszać akcelerację sprzętową? chociaż przy renderowaniu z podwójnym buforem poprawia się FPS, ale czas renderowania jest nadal ograniczony. nowoczesny sprzęt graficzny zwykle wymaga wielu optymalizacji podczas renderowania, zazwyczaj takich jak wygładzanie krawędzi, jest to bardzo intensywne obliczeniowo, jeśli nie potrzebujesz grafiki o wysokiej jakości, możesz oczywiście wyłączyć tę opcję. a to pozwoli ci zaoszczędzić trochę czasu.

Myślę, że to, czego naprawdę potrzebujesz, to system powtórek, który całkowicie zgadzam się z tym, o czym rozmawiali ludzie.

cynk
źródło
1
Zobacz dyskusję, dlaczego system powtórek nie jest możliwy. Program do wyświetlania ekranu nie jest przeznaczony dla żadnej konkretnej gry.
someguy,
10

Napisałem klasę, która zaimplementowała metodę GDI do przechwytywania ekranu. Ja też chciałem dodatkowej szybkości, więc po odkryciu metody DirectX (przez GetFrontBuffer) spróbowałem tego, spodziewając się, że będzie szybsza.

Byłem przerażony, gdy stwierdziłem, że GDI działa około 2,5x szybciej. Po 100 próbach przechwytywania mojego wyświetlacza z dwoma monitorami implementacja GDI wynosiła średnio 0,65 s na zrzut ekranu, podczas gdy metoda DirectX średnio 1,72 s. Tak więc GDI jest zdecydowanie szybsze niż GetFrontBuffer, według moich testów.

Nie udało mi się uruchomić kodu Brandrew w celu przetestowania DirectX przez GetRenderTargetData. Kopia ekranowa wyszła całkowicie czarna. Jednak może bardzo szybko skopiować ten pusty ekran! Będę majstrować przy tym i mam nadzieję, że uzyskam działającą wersję, aby zobaczyć prawdziwe wyniki.

rotanimod
źródło
Dziękuję za informację. Nie testowałem kodu Brandrew, ale wiem, że takie GetRenderTargetDatapodejście działa. Może napiszę własną odpowiedź, kiedy skończę aplikację. Lub możesz zaktualizować swoją, gdy wszystko już działa.
someguy
0,65 na zrzut ekranu ?! Dobra implementacja GDI (utrzymywanie urządzeń w pobliżu itp.) Powinna z łatwością wykonywać 30 klatek na sekundę w rozdzielczości 1920x1200 na nowoczesnym komputerze.
Christopher Oezbek
Zakładam, że jakość obrazu renderowanego przez GDI jest zdecydowanie gorsza niż DX
zinking
Przeprowadziłem ten test w C # z SlimDX i, o dziwo, uzyskałem takie same wyniki. Być może ma to związek z faktem, że używając SlimDX, trzeba stworzyć nowy strumień i nową bitmapę dla każdej aktualizacji ramki, zamiast tworzyć ją raz, przewijać i nadpisywać to samo miejsce.
Cesar
Tylko wyjaśnienie: w rzeczywistości „te same wyniki” odnosiły się do szybszego GDI - jak wspomniał @Christopher, 30 klatek na sekundę było bardzo wykonalne i nadal pozostawiało mnóstwo wolnego procesora.
Cesar,
8

Kilka rzeczy, które udało mi się zebrać: najwyraźniej użycie „sterownika lustrzanego” jest szybkie, chociaż nie znam sterownika OSS.

Dlaczego RDP jest tak szybki w porównaniu z innymi programami do zdalnego sterowania?

Wygląda na to, że niektóre zwoje StretchRect są szybsze niż BitBlt

http://betterlogic.com/roger/2010/07/fast-screen-capture/comment-page-1/#comment-5193

A ten, o którym wspomniałeś (fraps podpina się do dll D3D) jest prawdopodobnie jedynym sposobem dla aplikacji D3D, ale nie będzie działał z przechwytywaniem pulpitu Windows XP. Więc teraz żałuję, że nie było odpowiednika szybkości fraps dla normalnych okien pulpitu ... ktoś?

(Myślę, że z aerodynamiką możesz użyć haczyków podobnych do fraps, ale użytkownicy XP nie mieliby szczęścia).

Najwyraźniej zmienia się także głębia bitowa ekranu i / lub wyłącza przyspieszenie sprzętowe. może pomóc (i / lub wyłączenie aero).

https://github.com/rdp/screen-capture-recorder-program zawiera dość szybkie narzędzie do przechwytywania oparte na BitBlt oraz test porównawczy jako część swojej instalacji, który może pozwolić ci porównać prędkości BitBlt w celu ich optymalizacji.

VirtualDub ma również moduł do przechwytywania ekranu „opengl”, o którym mówi się, że jest szybki i robi takie rzeczy, jak wykrywanie zmian http://www.virtualdub.org/blog/pivot/entry.php?id=290

rogerdpack
źródło
Zastanawiam się, czy szybsze będzie użycie twojego "rejestratora przechwytywania ekranu" czy samodzielne użycie BitBlt? Czy w Twoim projekcie jest jakaś optymalizacja?
blez
Jeśli sam używasz Bitblt, możesz uniknąć dodatkowego memcpy (memcpy zwykle nie jest największym wąskim gardłem, chociaż dodaje trochę czasu - wspomniałem o tym tutaj tylko ze względu na jego narzędzie testowe, ale jeśli potrzebujesz czegoś lub bezpośredniego pokazu, to jest to miłe )
rogerdpack
8

W przypadku C ++ możesz użyć: http://www.pinvoke.net/default.aspx/gdi32/BitBlt.html
Może to nie działać we wszystkich typach aplikacji 3D / aplikacji wideo. Wtedy ten link może być bardziej przydatny, ponieważ opisuje 3 różne metody, których możesz użyć.

Stara odpowiedź (C #):
Możesz użyć System.Drawing.Graphics.Copy , ale nie jest to bardzo szybkie.

Przykładowy projekt, który napisałem robiąc dokładnie to: http://blog.tedd.no/index.php/2010/08/16/c-image-analysis-auto-gaming-with-source/

Planuję zaktualizować ten przykład przy użyciu szybszej metody, takiej jak Direct3D: http://spazzarama.com/2009/02/07/screencapture-with-direct3d/

A oto link do przechwytywania do wideo: Jak przechwycić ekran do wideo przy użyciu C # .Net?

Tedd Hansen
źródło
2
Ach, zapomniałem wspomnieć, że programuję w C (prawdopodobnie C ++) i nie planuję używać .NET. Strasznie przepraszam :/.
someguy
Znałem już BitBlt (GDI). Jednak przyjrzę się Direct3D. Dzięki!
someguy
Szukałem tego kilka tygodni temu, ale jeszcze nie zabrałem się za wdrożenie. Direct3D jest !! sposób !! szybciej niż wbudowana metoda C #, która korzysta z GDI +.
Tedd Hansen,
Zaktualizowałem mój oryginalny post. Zgodnie z linkiem, DirectX działa wolno, gdy trzeba wywołać GetFrontBufferData (). Czy warto wziąć to pod uwagę podczas nagrywania materiału z gry? Czy możesz to dla mnie kontekstualizować?
someguy
1
GDI jest powolne, więc nie nadaje się do domeny problemowej, DirectX lub OpenGL byłyby jedynymi rozsądnymi zaleceniami.
6

Wraz z systemem Windows 8 firma Microsoft wprowadziła interfejs Windows Desktop Duplication API. To jest oficjalnie zalecany sposób robienia tego. Jedną z fajnych funkcji, które ma do wyświetlania ekranu, jest to, że wykrywa ruch okna, dzięki czemu można przesyłać delty blokowe, gdy okna są poruszane, zamiast surowych pikseli. Informuje również, które prostokąty uległy zmianie, z jednej klatki do następnej.

Przykładowy kod firmy Microsoft jest dość złożony, ale interfejs API jest w rzeczywistości prosty i łatwy w użyciu. Przygotowałem przykładowy projekt, który jest znacznie prostszy niż oficjalny przykład:

https://github.com/bmharper/WindowsDesktopDuplicationSample

Dokumenty: https://docs.microsoft.com/en-gb/windows/desktop/direct3ddxgi/desktop-dup-api

Oficjalny przykładowy kod Microsoft: https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a

Ben Harper
źródło
Projekt Github działa doskonale na Windows 10, przetestowany z wideo internetowym i Resident Evil 7. Najlepsze jest to, że obciążenie procesora skaluje się z szybkością aktualizacji grafiki.
jw_
gdy tylko uruchomisz GPU-Z, program przestaje chwytać ekran.
Marino Šimić
5

Możesz wypróbować projekt open source C ++ WinRobot @git , potężny program do przechwytywania ekranu

CComPtr<IWinRobotService> pService;
hr = pService.CoCreateInstance(__uuidof(ServiceHost) );

//get active console session
CComPtr<IUnknown> pUnk;
hr = pService->GetActiveConsoleSession(&pUnk);
CComQIPtr<IWinRobotSession> pSession = pUnk;

// capture screen
pUnk = 0;
hr = pSession->CreateScreenCapture(0,0,1280,800,&pUnk);

// get screen image data(with file mapping)
CComQIPtr<IScreenBufferStream> pBuffer = pUnk;

Wsparcie :

  • Okno UAC
  • Winlogon
  • DirectShowOverlay
Kajman
źródło
1
To ... dużo haczyków niskiego poziomu. Szybkość przechwytywania jest niesamowita, jeśli masz uprawnienia administratora.
toster-cx
Uważam, że robot winobot jest bardzo mocny i płynny.
ashishgupta_mca
Studiowałem kod WinRobota i nie widziałem nic przełomowego w przechwytywaniu ekranu: używa tego samego CreateCompatibleDC..BitBlt. Chyba że jest jakaś magia, gdy jest to wykonywane w kontekście usługi?
szech,
@shekh: Twoje badanie było zbyt powierzchowne. Kod używa IDirectDrawSurface7-> BltFast () do skopiowania ekranu z powierzchni rysunkowej ekranu do powierzchni kopii DD, a następnie używa mapowania plików do skopiowania obrazu. Jest to dość skomplikowane, ponieważ kod działa w usłudze, w której nie można łatwo uzyskać dostępu do pulpitów.
Elmue
2

Sam robię to z DirectX i myślę, że jest tak szybki, jak byś chciał. nie mam szybkiego przykładu kodu, ale znalazłem to, co powinno być przydatne. wersja directx11 nie powinna się zbytnio różnić, directx9 może trochę bardziej, ale to jest droga

cppanda
źródło
2

Zdaję sobie sprawę, że poniższa sugestia nie odpowiada na twoje pytanie, ale najprostszą metodą, jaką znalazłem, aby uchwycić szybko zmieniający się widok DirectX, jest podłączenie kamery wideo do portu S-video karty graficznej i nagrywanie obrazów jako film. Następnie przenieś wideo z kamery z powrotem do pliku MPG, WMV, AVI itp. Na komputerze.

Pierre
źródło
2

Nagrywanie ekranu można wykonać w C # przy użyciu VLC API . Zrobiłem przykładowy program, aby to zademonstrować. Korzysta z bibliotek LibVLCSharp i VideoLAN.LibVLC.Windows . Dzięki temu wieloplatformowemu interfejsowi API można osiągnąć wiele innych funkcji związanych z renderowaniem wideo.

Aby zapoznać się z dokumentacją API, zobacz: LibVLCSharp API Github

using System;
using System.IO;
using System.Reflection;
using System.Threading;
using LibVLCSharp.Shared;

namespace ScreenRecorderNetApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Core.Initialize();

            using (var libVlc = new LibVLC())
            using (var mediaPlayer = new MediaPlayer(libVlc))
            {
                var media = new Media(libVlc, "screen://", FromType.FromLocation);
                media.AddOption(":screen-fps=24");
                media.AddOption(":sout=#transcode{vcodec=h264,vb=0,scale=0,acodec=mp4a,ab=128,channels=2,samplerate=44100}:file{dst=testvlc.mp4}");
                media.AddOption(":sout-keep");

                mediaPlayer.Play(media);
                Thread.Sleep(10*1000);
                mediaPlayer.Stop();
            }
        }
    }
}
Karthick
źródło
1
Do kogo to może dotyczyć: Należy pamiętać, że biblioteka libvlc jest udostępniana na licencji GPL. Jeśli nie zamierzasz wydawać swojego kodu na GPL, nie używaj libvlc.
Sebastian Cabot
To nie jest do końca dokładne, LibVLC to LGPL - została ponownie licencjonowana w 2011 roku. Sama aplikacja VLC pozostaje na licencji GPL: videolan.org/press/lgpl-libvlc.html
Andrew
0

Przechwytywanie pulpitu DXGI

Projekt, który przechwytuje obraz pulpitu z powieleniem DXGI. Zapisuje przechwycony obraz do pliku w różnych formatach obrazu (* .bmp; * .jpg; * .tif).

Ten przykład jest napisany w C ++. Potrzebujesz także doświadczenia z DirectX (D3D11, D2D1).

Co potrafi aplikacja

  • Jeśli masz więcej niż jeden monitor biurkowy, możesz wybrać.
  • Zmień rozmiar przechwyconego obrazu pulpitu.
  • Wybierz różne tryby skalowania.
  • W obrazie wyjściowym można pokazać lub ukryć ikonę myszy.
  • Możesz obrócić obraz dla obrazu wyjściowego lub pozostawić go jako domyślny.
gerdogdu
źródło