select a screen section ffmpeg c++ on macos

  avfoundation, c++, ffmpeg, macos, screen-recording

I am trying to record the screen on macos, with ffmpeg. I would like to be able to select a section of the screen instead of the whole desktop. I tried to set several options such as vf, with values like "crop=150:150:0:0", or video_size with value "150x150". The result was that the output video had the correct dimensions (150×150) but whole screen has been recrded instead of the specified section. Does anybody know another way to do that?

int ScreenRecorder::openVideoDevice() {
    value = 0;
    videoOptions = nullptr;
    pAVFormatContext = nullptr;

    pAVFormatContext = avformat_alloc_context();


    string dimension = to_string(width) + "x" + to_string(height);
    av_dict_set(&videoOptions, "video_size", dimension.c_str(), 0);   //option to set the dimension of the screen section to record
    value = av_dict_set(&videoOptions, "framerate", "25", 0);
    if (value < 0) {
        cerr << "Error in setting dictionary value (setting framerate)" << endl;
        exit(-1);
    }

    value = av_dict_set(&videoOptions, "preset", "ultrafast", 0);
    if (value < 0) {
        cerr << "Error in setting dictionary value (setting preset value)" << endl;
        exit(-1);
    }

    //The distance from the left edge of the screen or desktop
    value = av_dict_set(&videoOptions, "vf", ("crop=" + to_string(width) + ":" + to_string(height) + ":" + to_string(x_offset) + ":" +
        to_string(y_offset)).c_str(), 0);

    if (value < 0) {
        cerr << "Error in setting crop" << endl;
        exit(-1);
    }

    value = av_dict_set(&videoOptions, "pixel_format", "yuv420p", 0);
    if (value < 0) {
        cerr << "Error in setting pixel format" << endl;
        exit(-1);
    }
    
    pAVInputFormat = av_find_input_format("avfoundation");

    if (avformat_open_input(&pAVFormatContext, "1:none", pAVInputFormat, &videoOptions) != 0) {
        cerr << "Error in opening input device" << endl;
        exit(-1);
    }
    //get video stream infos from context
    value = avformat_find_stream_info(pAVFormatContext, nullptr);
    if (value < 0) {
        cerr << "Error in retrieving the stream info" << endl;
        exit(-1);
    }

    VideoStreamIndx = -1;
    for (int i = 0; i < pAVFormatContext->nb_streams; i++) {
        if (pAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            VideoStreamIndx = i;
            break;
        }
    }
    if (VideoStreamIndx == -1) {
        cerr << "Error: unable to find video stream index" << endl;
        exit(-2);
    }

    pAVCodecContext = pAVFormatContext->streams[VideoStreamIndx]->codec;
    pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id/*params->codec_id*/);
    if (pAVCodec == nullptr) {
        cerr << "Error: unable to find decoder video" << endl;
        exit(-1);
    }

    return 0;
}

Source: Windows Questions C++

LEAVE A COMMENT