Recorder: Recording Audio and Video
This tutorial demonstrates how you can record audio and video.
Warm-up
Become familiar with the Recorder and Camera API basics by learning about:
- Audio recorder
-
Initializing the Audio Recorder
Initialize the audio recorder for use.
-
Recording Audio
Start, stop, cancel, and pause recording an audio file, and release resources after finishing recording.
-
Initializing the Audio Recorder
- Video recorder
-
Initializing the Video Recorder
Initialize the devices for use.
-
Recording a Video
Prepare, record, commit, and cancel a video.
-
Initializing the Video Recorder
Initializing the Audio Recorder
To initialize the audio recorder for use:
-
To use the functions and data types of the Recorder API (in mobile and wearable applications), include the <recorder.h> header file in your application:
#include <recorder.h>
-
Create a handle for the audio recorder using the recorder_create_audiorecorder() function:
static recorder_h g_recorder; // Create recorder handle to record audio int error_code = recorder_create_audiorecorder(&g_recorder); if (error_code == RECORDER_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG , "error code = %d", error_code); } else { dlog_print(DLOG_ERROR, LOG_TAG , "error code = %d", error_code); }
After successfully creating the handle, the state of the audio recorder is set to RECORDER_STATE_CREATED.
-
To receive notifications about the audio recorder state changes, register a callback function using the recorder_set_state_changed_cb() function:
error_code = recorder_set_state_changed_cb(g_recorder, _state_changed_cb, NULL);
-
The callback function returns the following parameters:
- previous: The previous state of the audio recorder.
- current: The current state of the audio recorder.
- by_policy: If the state was changed by a policy, this is set to true.
- user_data: The custom data passed from the recorder_set_state_changed_cb() function.
The following example code implements a simple callback function that prints the previous and current audio recorder states:
static void _state_changed_cb(recorder_state_e previous, recorder_state_e current, bool by_policy, void *user_data) { dlog_print(DLOG_INFO, LOG_TAG , "_recorder_state_changed_cb (prev: %d, curr: %d)\n", previous, current); }
-
Before you can set any audio recorder attributes, set the audio codec for encoding the audio stream using the recorder_set_audio_encoder() function. Based on the audio codec, set the correct file format using the recorder_set_file_format() function. For example, if you set the codec to AAC, set the file format to 3GP. In addition, set the file name correctly according to the file format when you call the recorder_set_filename() function. The function takes as a parameter the full path of the file to which the recorded audio data is to be stored.
#define FILENAME_PREFIX "AUDIO" struct tm localtime = { 0 }; time_t rawtime = time(NULL); char filename[256] = { '\0' }; size_t size; // Set audio encoder error_code = recorder_set_audio_encoder(g_recorder, RECORDER_AUDIO_CODEC_AAC); // Set audio sample rate error_code = recorder_attr_set_audio_samplerate(rec_data.recorder, 44100); // Set file format according to audio encoder error_code = recorder_set_file_format(g_recorder, RECORDER_FILE_FORMAT_3GP); // Make file name if (localtime_r(&rawtime, &localtime) != NULL) { size = snprintf(filename, sizeof(filename), "%s/%s-%04i-%02i-%02i_%02i:%02i:%02i.3gp", app_get_data_path(), FILENAME_PREFIX, localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday, localtime.tm_hour, localtime.tm_min, localtime.tm_sec); } else { // Error handling } // Set file name according to file format error_code = recorder_set_filename(g_recorder, filename);
The following table lists the available audio codecs.
Table: Available audio codecs Value Description Notes RECORDER_AUDIO_CODEC_DISABLE Disable audio track RECORDER_AUDIO_CODEC_AMR AMR codec Set the sampling rate under 8000 and mono channel in the Emulator. RECORDER_AUDIO_CODEC_AAC AAC codec Set the sampling rate as 44100 and stereo channel in the Emulator. RECORDER_AUDIO_CODEC_VORBIS Vorbis codec RECORDER_AUDIO_CODEC_PCM PCM codec The following table lists the available audio devices.
Table: Available audio devices Value Description RECORDER_AUDIO_DEVICE_MIC Mic device RECORDER_AUDIO_DEVICE_MODEM Modem -
After setting the audio encoder, file format, and file name, you can set additional attributes for the audio recorder. The following example code sets the file size limit, encoder bitrate, audio device, and sampling rate:
// Set max file size to 1024 [kB] error_code = recorder_attr_set_size_limit(g_recorder, 1024); // Set bitrate of audio encoder error_code = recorder_attr_set_audio_encoder_bitrate(g_recorder, 28800); // Set audio device to microphone error_code = recorder_attr_set_audio_device(g_recorder, RECORDER_AUDIO_DEVICE_MIC); // Set audio sample rate error_code = recorder_attr_set_audio_samplerate(g_recorder, 44100);
-
To receive notifications about reaching the recording limit, register a callback function using the recorder_set_recording_limit_reached_cb() function:
error_code = recorder_set_recording_limit_reached_cb(g_recorder, _recorder_recording_limit_reached_cb, NULL);
-
The following example code implements a simple callback function that prints a notification about reaching the recording limit:
static void _recorder_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data) { dlog_print(DLOG_DEBUG, LOG_TAG , "Recording limit reached: %d\n", type); }
Recording Audio
To record audio:
-
To prepare the audio recorder for recording, use the recorder_prepare() function:
error_code = recorder_prepare(g_recorder);
After calling the function, the audio recorder state is set to RECORDER_STATE_READY. You can now start recording audio.
-
To start recording audio, use the recorder_start() function with the correct recorder handle:
error_code = recorder_start(g_recorder);
-
You can pause recording only when the audio recorder state is RECORDER_STATE_RECORDING. To check the state, use the recorder_get_state() function.
To pause recording audio, use the recorder_pause() function with the correct recorder handle:
error_code = recorder_pause(g_recorder);
To resume recording audio, use the recorder_start() function.
-
You can cancel recording only when the audio recorder state is RECORDER_STATE_RECORDING or RECORDER_STATE_PAUSED. To check the state, use the recorder_get_state() function.
To cancel recording audio, use the recorder_cancel() function with the correct recorder handle. The cancelled recording is discarded and no data is written to a file.
error_code = recorder_cancel(g_recorder);
-
You can stop recording only when the audio recorder state is RECORDER_STATE_RECORDING or RECORDER_STATE_PAUSED. To check the state, use the recorder_get_state() function.
To stop recording audio and save the recorded data to a file, use the recorder_commit() function. If the target file path has been set to an existing file, the existing file is replaced with the new audio file.
The following example code first checks the audio recorder's state, and then stops the recorder and stores the recorded data to a file:
// Check audio recorder state static bool _recorder_expect_state(recorder_h recorder, recorder_state_e expected_state) { recorder_state_e state; int error_code = recorder_get_state(recorder, &state); dlog_print(DLOG_INFO, LOG_TAG , "recorder state = %d, expected recorder state = %d", state, expected_state); if (state == expected_state) { return TRUE; } return FALSE; } // Stop recording and save recorded data if (_recorder_expect_state(g_recorder, RECORDER_STATE_RECORDING) || _recorder_expect_state(g_recorder, RECORDER_STATE_PAUSED)) { error_code = recorder_commit(g_recorder); if (error_code != RECORDER_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG , "error code = %d", error_code); return true; } }
-
After you have finished recording, release all resources associated with the audio recorder:
- Unregister the recording limit callback function using the recorder_unset_recording_limit_reached_cb() function.
error_code = recorder_unset_recording_limit_reached_cb(g_recorder);
- If the audio recorder state is RECORDER_STATE_READY, reset the media content and recorder state using the recorder_unprepare() function. The function sets the recorder state to RECORDER_STATE_CREATED.
error_code = recorder_unprepare(g_recorder);
- Unregister the state change callback function using the recorder_unset_state_changed_cb() function.
error_code = recorder_unset_state_changed_cb(g_recorder);
- Destroy the recorder handle using the recorder_destroy() function.
error_code = recorder_destroy(g_recorder);
- Unregister the recording limit callback function using the recorder_unset_recording_limit_reached_cb() function.
Initializing the Video Recorder
To initialize the video recorder:
- To use the functions and data types of the Camera API (in mobile and wearable applications) and Recorder (in mobile and wearable applications) APIs, include the <camera.h> and <recorder.h> header files in your application:
#include <camera.h> #include <recorder.h>
- To provide recording functionalities, the camera is configured while the camera handle is created. Then the recorder is configured. The following sections describe how to configure a camera and recorder.
#include <unistd.h> #include <cstdio> struct recdata { bool shutdown; recorder_h recorder; camera_h camera; }; static const int RECORD_TIME=2; static const int RECORD_LIMIT=4; #define FILENAME_PREFIX "VIDEO" static int g_bitrate = 288000; static int duration; static int playing=0; static int ret;
Configuring the Camera
To configure the camera:
-
Define a structure containing the handles to the media recorder and camera and a boolean variable specifying whether the recorder is switched off. You can declare variables to keep the record time, video file paths, bit rate, record limit, flag, and return value.
static recdata rec_data;
-
To use the camera, create the camera handle using the camera_create() function. The function's arguments are the camera handle and the hardware camera to access. If it succeeds, the camera state is changed to CAMERA_STATE_CREATED. Get the camera state using the camera_get_state() function:
int error_code = 0; rec_data.shutdown = FALSE; rec_data.camera = NULL; rec_data.recorder = NULL; // Create camera handle error_code = camera_create(CAMERA_DEVICE_CAMERA0, &rec_data.camera); if (error_code == CAMERA_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG , "error code = %d", error_code); } else { dlog_print(DLOG_ERROR, LOG_TAG , "error code = %d", error_code); }
-
Set a display for the preview to see what you are recording. To set a display for the preview, call the camera_set_display() function with a valid camera handle.
Registering Callback Functions
To register callback functions, which are useful in informing you when something has happened or changed in your application:
-
To monitor when the recording limit is reached, register a callback function using the recorder_set_recording_limit_reached_cb() function:
ret = recorder_set_recording_limit_reached_cb(rec_data.recorder, _recorder_recording_limit_reached_cb, 0);
-
Define the callback function that prints a notification about reaching the recording limit:
static void _recorder_recording_limit_reached_cb (recorder_recording_limit_type_e type, void *user_data) { dlog_print(DLOG_DEBUG, "Video Recorder", "Recording limit reached: %d\n", type); }
-
To check whether the callback function works properly, use the sleep() function to reach the recording limit:
ret = recorder_start(rec_data.recorder); sleep(RECORD_LIMIT+1); // Waits more than record limit ret = recorder_pause(rec_data.recorder);
-
To unregister the callback function, use the recorder_unset_recording_limit_reached_cb() function:
ret = recorder_unset_recording_limit_reached_cb(rec_data.recorder);
Configuring the Recorder
To configure the recorder:
-
When the camera state is CAMERA_STATE_CREATED, create the recorder handle using the recorder_create_videorecorder() function with a valid camera handle and record handle. If the function succeeds, the recorder state becomes RECORDER_STATE_CREATED. The recorder can also be created when camera is in other states. Get the recorder state using the recorder_get_state() function.
// Create the recorder handle error_code = recorder_create_videorecorder(rec_data.camera, &rec_data.recorder); if (error_code == RECORDER_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG , "error code = %d", error_code); } else { dlog_print(DLOG_ERROR, LOG_TAG , "error code = %d", error_code); }
-
To subscribe to notifications about recorder state changes, invoke the recorder_set_state_changed_cb() function to register the callback function. The parameters are: the valid recorder handle, the callback function, and data passed to the callback.
// Set the recorder state changed callback error_code = recorder_set_state_changed_cb(rec_data.recorder, on_state_changed_cb, NULL); if (error_code == RECORDER_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG , "error code = %d", error_code); } else { dlog_print(DLOG_ERROR, LOG_TAG , "error code = %d", error_code); }
-
The callback function receives the following parameters:
- Previous state of the recorder
- Current state of the recorder
- by_policy flag (true if the state is changed by policy)
- user_data passed from the callback registration function
// Recorder state changed callback - check state changes of the recorder static void on_state_changed_cb(recorder_state_e previous, recorder_state_e current, bool by_asm, void *data) { dlog_print(DLOG_DEBUG, LOG_TAG , "_recorder_state_changed_cb (prev: %d, curr: %d)\n", previous, current); }
-
The Recorder API supports the following attributes:
- Audio codec for encoding audio stream
- Video codec for encoding video stream
- File format
- File path to record
- Time limit of the recording file
- Maximum size of the recording file
- Audio device for recording
- Sampling rate of the audio stream
- Bitrate of the audio and video encoder
- Mute state of the recorder
- Slow motion rate
- Number of audio channels
To set the video codec for encoding a video stream, invoke the recorder_set_video_encoder() function. Choose one of the codecs from the recorder_video_codec_e enumeration. The following tables show the available codecs and formats.
Table: Available video codecs Value Description RECORDER_VIDEO_CODEC_H263 H263 codec RECORDER_VIDEO_CODEC_H264 H264 codec RECORDER_VIDEO_CODEC_MPEG4 MPEG4 codec RECORDER_VIDEO_CODEC_THEORA Theora codec Table: Available formats Value Description RECORDER_FILE_FORMAT_3GP 3GP RECORDER_FILE_FORMAT_MP4 MP4 RECORDER_FILE_FORMAT_AMR AMR RECORDER_FILE_FORMAT_ADTS ADTS RECORDER_FILE_FORMAT_WAV WAV Before setting the video codec, check the video codecs that your device supports. To check the codecs, use the recorder_foreach_supported_video_encoder() function. One of its parameters is a callback, which is called for each supported codec of the given recorder. If you set the return type as false in the _video_encoder_cb callback, you can search for a supporting codec. However, if you set the return type as true, you can get codecs which are supported in the target or Emulator. In the following example, the codec of the recorder is set to the first found supported resolution.
recorder_video_codec_e supported_codec; static bool _video_encoder_cb(recorder_video_codec_e codec, void *user_data) { recorder_video_codec_e * supported_codec = (recorder_video_codec_e*)user_data; *supported_codec = codec; return false; } error_code = recorder_foreach_supported_video_encoder(rec_data.recorder, _video_encoder_cb, &supported_codec); // Set the video encoder of the recorder error_code = recorder_set_video_encoder(rec_data.recorder, supported_codec);
-
Set the bitrate of the video encoder using the recorder_attr_set_video_encoder_bitrate() function. Set the file format for recording media stream by invoking the recorder_set_file_format() function. Before setting the file format, check the file formats your device supports using the recorder_foreach_supported_file_format() function. Furthermore, set the file path to store the recorded data by invoking the recorder_set_filename() function.
static int g_bitrate = 288000; struct tm localtime = { 0 }; time_t rawtime = time(NULL); char filename[256] = { '\0' }; size_t size; // Set the bitrate of the video encoder error_code = recorder_attr_set_video_encoder_bitrate(rec_data.recorder, g_bitrate); // Set the recording file format error_code = recorder_set_file_format(rec_data.recorder, RECORDER_FILE_FORMAT_MP4); // Make the file name if (localtime_r(&rawtime, &localtime) != NULL) { size = snprintf(filename, sizeof(filename), "%s/%s-%04i-%02i-%02i_%02i:%02i:%02i.mp4", app_get_data_path(), FILENAME_PREFIX, localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday, localtime.tm_hour, localtime.tm_min, localtime.tm_sec); } else { // Error handling } // Set the file path to store the recorded data error_code = recorder_set_filename(rec_data.recorder, filename);
-
Set the audio encoder, bitrate of the audio encoder, and sampling rate of audio using the recorder_set_audio_encoder(), recorder_attr_set_audio_encoder_bitrate(), and recorder_attr_set_audio_samplerate() functions, as with the video encoder.
Recording a Video
To record a video:
- Configure the camera and the recorder.
- Prepare the recorder.
Call the recorder_prepare() function with a valid recorder handle to change the recorder state to RECORDER_STATE_READY, one of the states in which you are able to start recording by calling the recorder_start() function.
// Prepare the recorder, resulting in setting the recorder state to RECORDER_STATE_READY error_code = recorder_prepare(rec_data.recorder);
- Start recording.
Start recording by calling the recorder_start() function with a valid recorder handle.
// Start the recorder error_code = recorder_start(rec_data.recorder);
After successfully starting the recorder, the file is removed automatically and replaced with a new one if you set the file path to an existing file. Note that the recorder_start() function is valid in the ready state (RECORDER_STATE_READY) or the paused state (RECORDER_STATE_PAUSED).
- Commit recording.
To stop recording and save the results, invoke the recorder_commit() function with a valid recorder handle. The results of the recording are saved to the previously configured file path. This function can be called if the recorder state is RECORDER_STATE_RECORDING or RECORDER_STATE_PAUSED.
// Stop recording and save the recorded data to the previously configured path error_code = recorder_commit(rec_data.recorder);
After this, the recorder state is changed to RECORDER_STATE_READY.
- Cancel recording.
If you do not want to save your recording, invoke the recorder_cancel() function with a proper recorder handle. The only difference between this and the recorder_commit() function is that the recording data is not written in the recording file.
// Stop recording without saving recorded data error_code = recorder_cancel(rec_data.recorder);
- Pausing recording.
To pause recording, use the recorder_pause() function with the valid recorder handle. To restart recording later, use the recorder_start() function. This function can be called if the recorder state is RECORDER_STATE_RECORDING.
// Pause recording error_code = recorder_pause(rec_data.recorder);
After this the recorder state is changed to RECORDER_STATE_PAUSED.
- Clean up after working with camera is finished.
When you have finished recording, invoke the recorder_unprepare() function to reset the media recorder. The required state for this function is RECORDER_STATE_READY. After calling the function, the recorder state is RECORDER_STATE_CREATED, which allows you to free all the recorder resources with the recorder_destroy() function.
// Unprepare the recorder error_code = recorder_unprepare(rec_data->recorder); // Destroy the recorder error_code = recorder_destroy(rec_data.recorder);
After this the recorder state is changed to RECORDER_STATE_NONE.