Code Monkey home page Code Monkey logo

Comments (5)

robmikh avatar robmikh commented on June 9, 2024 1

Yes it is, but it will require using another library to do the encoding. I would recommnd using the Windows.Media.Transcoding APIs. The idea would be to create a MediaTranscoder that's configured to take in raw BGRA8 input and output H264 samples. To feed the transcoder, you'll need to create a MediaStreamSource and respond to the SampleRequested event by providing frames in the form of MediaStreamSample objects which you can create using MediaStreamSample::CreateFromDirect3D11Surface.

I have a project here that demonstrates all that: https://github.com/robmikh/CaptureVideoSample. In particular, I would look at VideoRecordingSession.cpp.

It's worth noting that the media-foundation branch uses the Media Foundation APIs instead of Windows.Media.Transcoding. If you're saving the recordings to disk, I would use Windows.Media.Trancoding. The Media Foundation version exists to demonstrate that you can get the raw H264 samples. CaptureVideoSample just writes them to disk, but you could send them across the wire and decode them somewhere else. Unfortunately I haven't had luck getting the Media Foundation version to work on my ARM64 devices. I haven't had that issue with the Windows.Media.Transcoding version.

I'm going to close the issue, but feel free to ask questions!

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on June 9, 2024 1

In case others stumble across this issue, I'll list some other examples of video encoding:

  • SimpleRecorder - This is the oldest one. I would defer to the CaptureVideoSample project instead, but this project is interesting if you're using C#.
  • displayrecorder - This one is a port of CaptureVideoSample's media-foundation branch to Rust.

from windows.ui.composition-win32-samples.

gary-89 avatar gary-89 commented on June 9, 2024

Hi @robmikh, thanks for the contributions and nice repositories you shared.
I would like to better understand the different approaches I can use to record a screen using C# nowadays.
I have been working with WPF for many years, but, as Microsoft suggests, I am moving towards WinUI apps development.
All the source code I can find is either for Win32 or UWP (WinRT-based).
Do you have any recommendations?
The goal is to record the monitor and save the output to a .avi or .mp4 file.
Thanks!

from windows.ui.composition-win32-samples.

gary-89 avatar gary-89 commented on June 9, 2024

I don't understand how I can plug in your suggestion and use MediaTranscoder (PrepareFileTranscodeAsync()), MediaStreamSource etc...

Could you clarify how can I start encoding and write to an "output.mp4" file using the Texture2D bitmap frame generated by Direct3D11CaptureFramePool?

Here code I am referring to (in the WPF project):

public BasicCapture(IDirect3DDevice d, GraphicsCaptureItem i)
{
    item = i;
    device = d;
    d3dDevice = Direct3D11Helper.CreateSharpDXDevice(device);
    var dxgiFactory = new Factory2();
    var description = new SwapChainDescription1()
    {
        Width = item.Size.Width,
        Height = item.Size.Height,
        Format = Format.B8G8R8A8_UNorm,
        Stereo = false,
        SampleDescription = new SampleDescription()
        {
            Count = 1,
            Quality = 0
        },
        Usage = Usage.RenderTargetOutput,
        BufferCount = 2,
        Scaling = Scaling.Stretch,
        SwapEffect = SwapEffect.FlipSequential,
        AlphaMode = AlphaMode.Premultiplied,
        Flags = SwapChainFlags.None
    };
    swapChain = new SwapChain1(dxgiFactory, d3dDevice, ref description);

    framePool = Direct3D11CaptureFramePool.Create(
        device,
        DirectXPixelFormat.B8G8R8A8UIntNormalized,
        2,
        i.Size);
    session = framePool.CreateCaptureSession(i);
    lastSize = i.Size;
    

    framePool.FrameArrived += OnFrameArrived;
}

private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
{
  var newSize = false;

  using (var frame = sender.TryGetNextFrame())
  {
	  if (frame.ContentSize.Width != lastSize.Width ||
		  frame.ContentSize.Height != lastSize.Height)
	  {
		  // The thing we have been capturing has changed size.
		  // We need to resize the swap chain first, then blit the pixels.
		  // After we do that, retire the frame and then recreate the frame pool.
		  newSize = true;
		  lastSize = frame.ContentSize;
		  swapChain.ResizeBuffers(
			  2,
			  lastSize.Width,
			  lastSize.Height,
			  Format.B8G8R8A8_UNorm,
			  SwapChainFlags.None);
	  }

	  using (var backBuffer = swapChain.GetBackBuffer<Texture2D>(0))
	  using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
	  {
		  d3dDevice.ImmediateContext.CopyResource(bitmap, backBuffer);
		  _videoEncoder.AddFrame(bitmap);
	  }

  } // Retire the frame.

  swapChain.Present(0, PresentFlags.None);

  if (newSize)
  {
	  framePool.Recreate(
		  device,
		  DirectXPixelFormat.B8G8R8A8UIntNormalized,
		  2,
		  lastSize);
  }
}

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on June 9, 2024

I would take a look at the SimpleRecorder repo. The approach should be the same between WPF, UWP, and WinAppSDK. The only difference would be how the preview is hooked up into the UI.

from windows.ui.composition-win32-samples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.