Capture local screenshots

Updated

Use the Agora Recording SDK to capture screenshots.

On-Premise Recording SDK lets you intercept remote video frames during real-time interaction to review live broadcast content and ensure compliance with regulations.

This article shows you how to use the On-Premise Recording SDK to implement the screenshot feature in your project.

Understand the tech

The On-Premise Recording SDK supports capturing screenshots of remote video in both individual and composite recording modes. You can also take screenshots without recording. The supported formats are:

  • H.264/H.265 encoded frame: Returns video frame data in the original encoding format
  • YUV frame: Returns video frame data in YUV format
  • JPG frame: Returns video frame data in JPG format
  • JPG file: Saves the screenshot as a JPG file in the specified directory

Prerequisites

Before using layouts, complete the steps in the Quickstart guide to integrate the SDK and set up basic recording.

Implementation

To implement the local screenshot function, follow these steps:

  1. Initialize a recorder instance. Call enableRecorderVideoFrameCapture to enable or disable the screenshot function.
  2. After you join the channel, use the IRecorderVideoFrameObserver interface to receive callbacks for different types of video frames. These callbacks let you access the captured video data.

The following sample shows how to configure and enable video frame capture:

// Create an observer to receive video frames
std::unique_ptr<RecorderVideoFrameObserver> videoFrameObserver{new RecorderVideoFrameObserver()};
agora::rtc::RecorderVideoFrameCaptureConfig videoFrameCaptureConfig;
if(config.frameCaptureConfig.enable){
    // Set the screenshot type
    videoFrameCaptureConfig.videoFrameType = static_cast<agora::rtc::VideoFrameCaptureType>(config.frameCaptureConfig.videoFrameType);
    // JPG frames and JPG files support setting the screenshot interval
    videoFrameCaptureConfig.jpgCaptureIntervalInSec = config.frameCaptureConfig.jpgCaptureInterval;
    // JPG files require setting the save path for JPG files
    videoFrameCaptureConfig.jpgFileStorePath = config.frameCaptureConfig.jpgFileStorePath.c_str();

    // Set the observer
    videoFrameCaptureConfig.observer = videoFrameObserver.get();
    // Call enableRecorderVideoFrameCapture to enable video frame capture
    recorder->enableRecorderVideoFrameCapture(true, videoFrameCaptureConfig);
}

The SDK supports capturing H.264/H.265 encoded frames, YUV format frames, JPG format frames, and JPG files. Refer to the following RecorderVideoFrameCaptureConfig settings for each type of video frame:

  • H.264/H.265 encoded frames

    videoFrameCaptureConfig.videoFrameType = agora::rtc::VIDEO_FORMAT_ENCODED_FRAME_TYPE;
  • YUV format frame

    videoFrameCaptureConfig.videoFrameType = agora::rtc::VIDEO_FORMAT_YUV_FRAME_TYPE;
  • JPG format frame

    videoFrameCaptureConfig.videoFrameType = agora::rtc::VIDEO_FORMAT_JPG_FRAME_TYPE;
    // Capture a screenshot every 3 seconds
    videoFrameCaptureConfig.jpgCaptureIntervalInSec = 3;
  • JPG files

    videoFrameCaptureConfig.videoFrameType = agora::rtc::VIDEO_FORMAT_JPG_FILE_TYPE;
    // Save one image every 10 seconds
    videoFrameCaptureConfig.jpgCaptureIntervalInSec = 10;
    // Make sure the directory exists and is writable
    videoFrameCaptureConfig.jpgFileStorePath = "/tmp/screenshots/";

Get the captured video frames

The IRecorderVideoFrameObserver interface provides callbacks for each video frame format. Use these callbacks to access the captured data.

class RecorderVideoFrameObserver : public agora::rtc::IRecorderVideoFrameObserver {
public:
    ~RecorderVideoFrameObserver() {}

    // YUV data callback
    void onYuvFrameCaptured(const char* channelId, agora::user_id_t userId,
                            const agora::media::base::VideoFrame *frame) override {
        // Handle YUV video frame
        printf("Received YUV frame: channel %s, user %u\n", channelId, userId);
    }

    // H.264/H.265, JPG frame data callback
    void onEncodedFrameReceived(const char* channelId, agora::user_id_t userId,
                                const uint8_t* imageBuffer, size_t length,
                                agora::rtc::EncodedVideoFrameInfo videoEncodedFrameInfo) override {
        // Handle encoded video frame
        printf("Received encoded frame: channel %s, user %u, data length %zu\n", channelId, userId, length);
    }

    // JPG file save callback
    void onJPGFileSaved(const char* channelId, agora::user_id_t userId,
                        const char* jpgFilePath) override {
        // JPG file saved successfully
        printf("JPG file saved: channel %s, user %u, path %s\n", channelId, userId, jpgFilePath);
    }
};

Stop video frame capture

To stop video frame capture, call enableRecorderVideoFrameCapture again and set the enable parameter to false:

// Stop the screenshot function
recorder->enableRecorderVideoFrameCapture(false, videoFrameCaptureConfig);

Reference

This section provides additional details and related considerations.

Development considerations

Video subscription settings

When you use the screenshot feature with YUV, JPG frame, or JPG file formats, set VideoSubscriptionOptions.encodedFrameOnly to false when calling subscribeVideo or subscribeAllVideo. The default is false.

Recording and screenshots are independent

You can take screenshots without recording. The startRecording method controls recording and does not affect screenshots.

API reference