Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kirides/screencapture
This repository has been moved to https://github.com/kirides/go-d3d
https://github.com/kirides/screencapture
com-interop d3d11 go golang idxgioutputduplication screen-capture screen-sharing windows
Last synced: 21 days ago
JSON representation
This repository has been moved to https://github.com/kirides/go-d3d
- Host: GitHub
- URL: https://github.com/kirides/screencapture
- Owner: kirides
- License: other
- Archived: true
- Created: 2021-05-07T17:27:54.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-12-27T09:32:01.000Z (almost 2 years ago)
- Last Synced: 2024-08-05T17:30:40.625Z (4 months ago)
- Topics: com-interop, d3d11, go, golang, idxgioutputduplication, screen-capture, screen-sharing, windows
- Language: Go
- Homepage:
- Size: 47.9 KB
- Stars: 54
- Watchers: 5
- Forks: 8
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-hacking-lists - kirides/screencapture - This repository has been moved to https://github.com/kirides/go-d3d (Go)
README
# Screencapture
This repository has been moved to https://github.com/kirides/go-d3d
## Motivation
I wanted to learn more about `COM` interop with Go and create a somewhat usable screen sharing tool
## Libaries used
This application uses D3D11 `IDXGIOutputDuplication` to create a somewhat _realtime_ desktop presentation
- `github.com/mattn/go-mjpeg` for mjpeg streaming
- `github.com/kbinani/screenshot` for comparison with GDI `BitBlt` (slightly modified source, to support re-using `image.RGBA`)
- `golang.org/x/exp/shiny/driver/internal/swizzle` for faster BGRA -> RGBA conversion (see [shiny LICENSE](./swizzle/LICENSE))
- `github.com/pixiv/go-libjpeg/jpeg` for fast jpeg encoding
- enable with `go build -tag jpegturbo`## Demo
Just build the application and run it.
It should serve all your monitors on an URL like `http://127.0.0.1:8023/watch?screen=N`
where `screen=N <- N` is the monitor index, starting at zero (`0`).By changing the lines in `cmd/example/main.go` regarding the streaming, you can switch between GDI `BitBlt` or `IDXGIOutputDuplication`
```go
// ...
framerate := 10
for i := 0; i < n; i++ {
// ...
// streamDisplay(ctx, i, framerate, stream) // <= USE GDI BitBlt
streamDisplayDXGI(ctx, i, framerate, stream) // <= USE IDXGIOutputDuplication
// captureScreenTranscode(ctx, i, desiredFps)
http.HandleFunc(fmt.Sprintf("/mjpeg%d", i), stream.ServeHTTP)
}
// ...
```### screen recording with ffmpeg
The code contains the function `captureScreenTranscode` which allows you to record the
selected screen directly into ffmpeg and transcode it to h264 in an mp4 container.## Performance
Performance _is not_ optimized to 100%, there are still thing that could be improved.
- only copying the dirty-rectangles (less GPU<->CPU communication)
- faster swizzle implementation using AVX/2 (less time for converting the BGRA texture)
- _profile ... profile ... profile_Overall the current implementation is about 2-5x faster than GDI `BitBlt` (depending on the resolution,
the higher the bigger the difference) and uses a lot less resources for cases where there arent any changes to the screen.## app.manifest
To make use of `IDXGIOutput5::DuplicateOutput1`, an application has to provide support for `PerMonitorV2` DPI-Awareness (Windows 10 1703+)
This is usually done by providing an my-executable.exe.manifest file either next to the executable, or as an embedded resource.In this application there are calls to `IsValidDpiAwarenessContext` and `SetThreadDpiAwarenessContext` which circumvent the requirement.