Recording videos with Qt5

published at 06.03.2013 16:24 by Jens Weller

I've started in February a little series about Qt5, and started with implementing a simple MP3 player with Qt5 Multimedia APIs. While I loved the thought of having a simple, multi platform MP3 player written in Qt5, it was not the original reason to take a look into Qt5 Multimedia capabilities. Something else had raised my attention: to be able to record videos.

Recording a video seems an easy task, but as I organized last years Meeting C++ conference, I tried to find a fitting program for the job. Windows or Linux, easily to handle, as staff should not need to be trained on the tool longer then needed, and doing a fairly good job. No big deal, at least with the last point we managed to screw up, as you might already know from last years conference. Of course there are lots of programs, which already can record from web cams videos, which is one of my goals. But most of them are rather complicated, they offer such a large feature set, that recording videos is only one of them. Last year I used Windows Movie Maker, as its offers easy recording, but still the tool managed to record video in only 240p, and that's not quite as I had planned for it. So, with all this experience, I was looking at Qt5, and suddenly realizing, that it offers Video Recordings. Worth a shot, so I implemented my own little video recording program with Qt5.

Before I dive into the code, some words about image quality in videos. Recording with Webcams gives you if you select a HD Web cam also HD Videos. But that doesn't say anything about the image quality. I have good, full HD Web cams from Logitech, which do a fairly good job, as long as there is enough light. If the light settings are dimmed in the room, the picture will get more noisy. When recording talks, everything between your speaker and your microphone can become a problem. So, when recording talks, one usually also should try to record the speakers audio.

Implementation

I want my video recording program to be easy, as I need to be able to let other easily record with it. My mother should be able to do it. So there is a simple interface, consisting of a QStackWidget, 2 Buttons (Record and Options) and a Listview. Again, I've decided to use QWidgets for Desktop, instead of QML. The StackWidget contains the QCameraViewFinder, which will display the web cams view in my program. It also contains a QVideoWidget, as I want to be able to open and playback the recordings inside the program. This is how it looks for now:

../../files/blog/vr.png

So lets take a look at the code. Most code is ui/event related, its not very complicated to record videos in Qt5. The Multimedia Framework of Qt5 already offers the important classes:

ui->setupUi(this);
camera = new QCamera(this);//1

ui->cameraViewer->setCamera(camera);//2

player = new QMediaPlayer(this);//3

videowidget = new QVideoWidget;//4
ui->stackedWidget->addWidget(videowidget);
player->setVideoOutput(videowidget);

recorder = new QMediaRecorder(camera,this);//5

auto&& settings = recorder->videoSettings();//6
settings.setResolution(1280,720);
settings.setQuality(QMultimedia::VeryHighQuality);
settings.setFrameRate(30.0);
recorder->setVideoSettings(settings);

camera->setCaptureMode(QCamera::CaptureVideo);//7
camera->start();//8
ui->cameraViewer->setFocus(camera->focus());//9

 This code is in the constructor of the mainwindow, and handles most initialization work which needs to be done:

  1. Creating a QCamera object
  2. Initialize the Viewfinder with the camera object
  3. Create a QMediaPlayer for playing back the recordings
  4. Setting up the playback infrastructure (similar to the mp3 player)
  5. Creating the QMediaRecorder object (obviously for recording)
  6. Doing some settings, I'd like to record as default at 720p for now
  7. Set the capturing mode, one can also capture still images with the QCamera, but for video recording a different mode is needed
  8. Start the camera interals. ViewFinder will now show camera view, but no recording.
  9. Actually I wrapped the Cameraviewer in a helper class, showing a gauge when focus/zooming is supported, there fore I hand over here the focus object to the helper class.

So, everything is setup, all thats missing is the recording method, which will start with the button press on "Start recording":

if(ui->btn_record->text()== tr("Start recording"))
{
    if(ui->stackedWidget->currentIndex() !=0)//1
    {
        ui->stackedWidget->setCurrentWidget(ui->cameraViewer);//2
        player->stop();
    }
    QString name = filename + QDateTime::currentDateTime().toString("dd.MM.yy-h-m-s");//3
    recorder->setOutputLocation(QUrl::fromLocalFile(outputpath + "/" + name + ".mp4"));
    recorder->record();//4
    ui->btn_record->setText(tr("Stop recording"));
    ui->btn_options->setEnabled(false);
}
else
{
    recorder->stop();
    ui->btn_options->setEnabled(true);
    ui->list_recordings->addItem(recorder->outputLocation().toLocalFile());
    ui->btn_record->setText(tr("Start recording"));
}

Again, I've been a bit lazy, and made the button have two functionalities start and stop. The details:

  1. First I check, if the VideoWidget is not on top of our stack!
  2. If, pull the ViewFinder in front and make sure the player also stops playing.
  3. Next, I set the file name, I want the recording date and time be part of it, and also have a certain prefix for it. In the Options one can choose where to put the videos and how to name them.
  4. The recorder will start recording after this line. And it will do so, until stop() is called.

One thing I still need to implement, to be able to record sound a the same time, yet it will mostly take the cameras microphone to record with. This is the only implication which I found in the API so far. While its perfectly fine that QAudioRecorder is derived from QMediaRecorder, I can't determine the audio source for my video recording. Maybe this is an recording issue, that you can not record sound and video from different sources into one video. Also I have to add, that the video recording is currently a little bit limited with the support on all platforms. For now this program will work perfectly under Linux, but with Qt5.0.1 not under Windows. I couldn't yet test it under Mac.

Join the Meeting C++ patreon community!
This and other posts on Meeting C++ are enabled by my supporters on patreon!