Content and capture

The console keeps a library of captures and imported media, and it can grab the finished screen as a screenshot or a video clip. Both live in SharpProspero.Platform. The library and capture services are permission-gated: a service refuses with a ProsperoException when the running module is not allowed to reach it, so treat every open as something that can fail.

The content library

ContentLibrary lists the photos and videos on the console, counts them, and totals their size. Open it, query it, dispose it. The content type comes from SharpProspero.Interop.Content.

using SharpProspero.Platform;
using SharpProspero.Interop.Content;

using var library = ContentLibrary.Open();
long photos = library.Count(SceContentSearchContentType.Photo);
foreach (ContentItem item in library.List(SceContentSearchContentType.Photo))
    Show(item.Title, item.Path, item.Size);

A ContentItem carries the ContentId, Type, MimeType, Title, Path, IconPath, Size, and an Available flag. Count returns how many items of a type exist. List reads one page of them, sorted by title: it returns at most ContentSearch.MaxLimit rows (92) per call, so walk a larger library by raising its offset argument until a call returns fewer rows than it asked for. Open takes an optional working-heap size; the default, ContentLibrary.DefaultMemorySize, is 3 MB and suits ordinary listing.

Listing needs the content-search permission. Without it, the first query raises a ProsperoException whose code is ContentSearch.PermissionRequired.

Reading one item’s metadata

ContentMetadata reads the individual fields of one item, opened by path or by content id from the library. Each field is typed.

using ContentMetadata meta = library.OpenMetadata(item.Path);
string title = meta.GetText(ContentSearch.FieldTitle);
long width = meta.GetInt(ContentSearch.FieldWidth);
double duration = meta.GetFloat(ContentSearch.FieldDuration);

GetText, GetInt, GetFloat, and GetTick read a named field in the type it stores, and GetFieldInfo reports that type and the field’s byte size when you need to choose. GetText returns an empty string for a field that is not text. The names are constants on SharpProspero.Interop.Content.ContentSearch: FieldTitle, FieldMimeType, FieldCreatedTime, FieldSize, FieldWidth, FieldHeight, and FieldDuration.

Exporting a file into the library

ContentExporter copies a file a module produced — a rendered image, a recording — into the console’s content library so it shows up alongside the user’s own captures.

using var exporter = ContentExporter.Open();
string savedPath = exporter.Export("/data/render.png", "My Render", ContentExport.FormatImagePng);

Export takes the source path, a display title, and the media type, and returns the path the file was written to inside the library. ContentExport names the media types: FormatImageJpeg, FormatImagePng, FormatImageGif, FormatVideoMp4, and FormatVideoWebm.

Deleting content

ContentDeleter removes a user-owned item — a screenshot, a clip, a download — by path or by id.

using var deleter = ContentDeleter.Open();
deleter.DeleteByPath("/user/photo/old.png");
deleter.DeleteById(contentId);

Deletion is permanent. Only user-owned content can be removed, and the delete does not prompt, so confirm with the user before calling it.

Capturing the finished screen

ShareCapture captures the whole finished screen — the application together with the system overlays — and saves it to the console’s capture gallery. It is the capture the share button drives: a 2K or 4K screenshot, or the last several seconds of output as a clip. This differs from encoding a drawing surface, which captures only what the application itself drew (see Graphics).

using SharpProspero.Platform;
using SharpProspero.Interop.Share;

using var share = ShareCapture.Start();
share.CaptureScreenshot(ScreenshotFormat.Png4K);   // saved to the gallery in the background
share.CaptureRecentClip(secondsBack: 30);          // save the last 30 seconds as a clip

Captures are asynchronous: each call returns a request id and the image or clip is written in the background. RecordingStatus reports whether the 2K and 4K clip recorders are stopped, paused or running. Block(ShareFeature.Screenshot) prevents capture while a sensitive screen is shown, and Allow re-enables it. SetScreenshotOverlay(filePath, marginX, marginY, origin) lays an image over captured screenshots, anchored by a ScreenshotOrigin corner, edge or center point with the given margins. Start takes the service’s heap size and helper-thread priority when the defaults do not suit.

Live capture of the composited screen

SystemAvCapture reads the live system-composited video — the finished screen the whole system draws — for a recorder or a stream, rather than saving a gallery clip. It opens a video channel only; no audio reaches the caller through this type.

This is an advanced, privileged surface. The capture service runs behind a system channel, and the process must hold the authority to reach it, which a plain application sandbox does not. Opening it without that authority fails with a permission error. Treat it as best-effort.

using SharpProspero.Platform;
using SharpProspero.Interop.AvCapture;

using var capture = SystemAvCapture.Open();
capture.OpenVideo(Avcap2VideoConfig.Create());
capture.Start();
while (recording)
{
    if (capture.TryReadVideo(out Avcap2VideoFrameInfo frame) && frame.IsValid)
        Encode(frame);          // a privileged consumer reads the frame planes
}
capture.Stop();

Avcap2VideoConfig.Create() returns a cleared configuration. Kind selects the channel — a non-zero value opens the primary one — and Mode selects a sub-mode. The default mode reads no further fields. Modes one and two need FrameAreaAddress and FrameAreaLength to name direct memory that is already mapped and at least that large. Mode one also needs AreaAddress and AreaLength; mode two accepts that pair only when both are set or both are clear. The open call is refused when any of these is missing or short.

GetFramePitch reports the row pitch of the captured frames, IsVideoOpen and IsStarted report state, and CloseVideo closes the channel while leaving the service running. The frame descriptor’s leading words are a service-internal layout; IsValid is what a caller checks.

For a recording path that needs no elevated privilege, save a gallery clip with ShareCapture, or encode the application’s own frames with the image encoders on the Graphics page.

  • Packages and devices — installing titles and reading connected devices.
  • System services — the permission model behind these services.
  • Media — decoding and playing back the video files the library holds.

Copyright © SvenGDK 2026. Distributed under the GPL-3.0-or-later license.

This site uses Just the Docs, a documentation theme for Jekyll.