@@ -173,6 +173,124 @@ fn main() {
173173}
174174```
175175
176+ ## Stream-based encoding example
177+
178+ Instead of writing directly to a file, you can encode into an in-memory stream using ` VideoEncoder::new_from_stream ` . This is useful when you need to send the encoded video over a network, pipe it to another process, or process it further before saving.
179+
180+ ``` rust
181+ use std :: io :: {self , Write };
182+ use std :: time :: Instant ;
183+
184+ use windows :: Storage :: Streams :: InMemoryRandomAccessStream ;
185+ use windows :: core :: Interface ;
186+ use windows_capture :: capture :: {Context , GraphicsCaptureApiHandler };
187+ use windows_capture :: encoder :: {
188+ AudioSettingsBuilder , ContainerSettingsBuilder , VideoEncoder , VideoSettingsBuilder ,
189+ };
190+ use windows_capture :: frame :: Frame ;
191+ use windows_capture :: graphics_capture_api :: InternalCaptureControl ;
192+ use windows_capture :: graphics_capture_picker :: GraphicsCapturePicker ;
193+ use windows_capture :: settings :: {
194+ ColorFormat , CursorCaptureSettings , DirtyRegionSettings , DrawBorderSettings ,
195+ MinimumUpdateIntervalSettings , SecondaryWindowSettings , Settings ,
196+ };
197+
198+ struct StreamCapture {
199+ encoder : Option <VideoEncoder >,
200+ stream : InMemoryRandomAccessStream ,
201+ start : Instant ,
202+ }
203+
204+ impl GraphicsCaptureApiHandler for StreamCapture {
205+ type Flags = (i32 , i32 );
206+ type Error = Box <dyn std :: error :: Error + Send + Sync >;
207+
208+ fn new (ctx : Context <Self :: Flags >) -> Result <Self , Self :: Error > {
209+ // Create an in-memory stream that the encoder will write into.
210+ let stream = InMemoryRandomAccessStream :: new ()? ;
211+
212+ let encoder = VideoEncoder :: new_from_stream (
213+ VideoSettingsBuilder :: new (ctx . flags. 0 as u32 , ctx . flags. 1 as u32 ),
214+ AudioSettingsBuilder :: default (). disabled (true ),
215+ ContainerSettingsBuilder :: default (),
216+ stream . cast ()? ,
217+ )? ;
218+
219+ Ok (Self {
220+ encoder : Some (encoder ),
221+ stream ,
222+ start : Instant :: now (),
223+ })
224+ }
225+
226+ fn on_frame_arrived (
227+ & mut self ,
228+ frame : & mut Frame ,
229+ capture_control : InternalCaptureControl ,
230+ ) -> Result <(), Self :: Error > {
231+ print! (
232+ " \ r Streaming for: {} seconds | Buffer size: {} bytes" ,
233+ self . start. elapsed (). as_secs (),
234+ self . stream. Size ()?
235+ );
236+ io :: stdout (). flush ()? ;
237+
238+ self . encoder. as_mut (). unwrap (). send_frame (frame )? ;
239+
240+ if self . start. elapsed (). as_secs () >= 6 {
241+ self . encoder. take (). unwrap (). finish ()? ;
242+
243+ let size = self . stream. Size ()? ;
244+ println! (" \ n Capture finished. Stream contains {size} bytes." );
245+
246+ // Read the encoded bytes from the in-memory stream.
247+ let reader = windows :: Storage :: Streams :: DataReader :: CreateDataReader (
248+ & self . stream. GetInputStreamAt (0 )? ,
249+ )? ;
250+ reader . LoadAsync (size as u32 )? . join ()? ;
251+
252+ let mut bytes = vec! [0u8 ; size as usize ];
253+ reader . ReadBytes (& mut bytes )? ;
254+ std :: fs :: write (" stream_output.mp4" , & bytes )? ;
255+
256+ println! (" Saved stream to stream_output.mp4" );
257+ capture_control . stop ();
258+ }
259+
260+ Ok (())
261+ }
262+
263+ fn on_closed (& mut self ) -> Result <(), Self :: Error > {
264+ println! (" Capture session ended" );
265+ Ok (())
266+ }
267+ }
268+
269+ fn main () {
270+ let item = GraphicsCapturePicker :: pick_item (). expect (" Failed to pick item" );
271+
272+ let Some (item ) = item else {
273+ println! (" No item selected" );
274+ return ;
275+ };
276+
277+ let size = item . size (). expect (" Failed to get item size" );
278+
279+ let settings = Settings :: new (
280+ item ,
281+ CursorCaptureSettings :: Default ,
282+ DrawBorderSettings :: Default ,
283+ SecondaryWindowSettings :: Default ,
284+ MinimumUpdateIntervalSettings :: Default ,
285+ DirtyRegionSettings :: Default ,
286+ ColorFormat :: Rgba8 ,
287+ size ,
288+ );
289+
290+ StreamCapture :: start (settings ). expect (" Stream capture failed" );
291+ }
292+ ```
293+
176294## DXGI Desktop Duplication example
177295
178296``` rust
0 commit comments