Example Recorder Implementation
Below are the header and cpp files for a Media Recorder Implementation, in order for this recorder to be used by the C++ SDK it must be passed to the conference service as
using the dolbyio::comms::services::media_io
. Now when a conference is joined all incoming media will be passed to the recorder implementation.
The recorder should be configured appropriately to be used for handling encoded or raw video and PCM/AAC audio. The application should set this configuration before passing the recorder implementation to the conference service.
The interfaces inheritted from by this custom_recorder example must be implemented by any custom recorder which wishes to receive video and audio frames.
- At the bottom of the page is a sample CMakeLists.txt which shows how to create a library for this custom recorder, then the library can be linked against the executable shown in the
Sample application section if you want to use a custom recorder module.
custom_recorder.h
/***************************************************************************
* This program is licensed by the accompanying "license" file. This file is
* distributed "AS IS" AND WITHOUT WARRANTY OF ANY KIND WHATSOEVER, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright (C) 2022-2023 by Dolby Laboratories.
***************************************************************************/
#include <dolbyio/comms/media_engine/media_engine.h>
#include <dolbyio/comms/sdk.h>
#include <memory>
#include <string>
class custom_recorder_impl : private dolbyio::comms::audio_sink,
private dolbyio::comms::video_sink,
private dolbyio::comms::video_sink_encoded {
public:
enum class audio_format { NONE, PCM, AAC };
enum class video_format { NONE, ENCODED, ENCODED_OPTIMIZED, YUV };
custom_recorder_impl(dolbyio::comms::sdk& sdk, video_format video, audio_format audio);
~custom_recorder_impl() override = default;
dolbyio::comms::video_sink* video_raw();
// audio_recorder interface
void handle_audio(const std::string&, const std::string&, const int16_t*, size_t, int, size_t) override;
// video_recorder_yuv interface
void handle_frame(std::unique_ptr<dolbyio::comms::video_frame>) override;
// video_recorder_encoded interface
dolbyio::comms::video_sink_encoded::decoder_config configure_encoded_sink(const std::string&,
const std::string&) override;
void handle_frame_encoded(const std::string&, std::unique_ptr<dolbyio::comms::encoded_video_frame>) override;
decoder_config decoder_configuration() const override;
private:
dolbyio::comms::sdk& sdk_;
audio_format af_{audio_format::NONE};
video_format vf_{video_format::NONE};
};
custom_recorder.cc
/***************************************************************************
* This program is licensed by the accompanying "license" file. This file is
* distributed "AS IS" AND WITHOUT WARRANTY OF ANY KIND WHATSOEVER, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright (C) 2022-2023 by Dolby Laboratories.
***************************************************************************/
#include "custom_recorder.h"
using decoder_config = dolbyio::comms::video_sink_encoded::decoder_config;
custom_recorder_impl::custom_recorder_impl(dolbyio::comms::sdk& sdk, video_format video, audio_format audio)
: sdk_(sdk), af_(audio), vf_(video) {
switch (vf_) {
case custom_recorder_impl::video_format::YUV: {
// install event handlers for video track added events
// create new sinks per video track, and install them on the sdk when track are added.
break;
}
case custom_recorder_impl::video_format::ENCODED:
case custom_recorder_impl::video_format::ENCODED_OPTIMIZED: {
wait(sdk_.media_io().set_encoded_video_sink(this));
break;
}
case custom_recorder_impl::video_format::NONE: {
wait(sdk_.media_io().set_encoded_video_sink(nullptr));
break;
}
}
if (af_ != custom_recorder_impl::audio_format::NONE) {
wait(sdk_.media_io().set_audio_sink(this));
} else {
wait(sdk_.media_io().set_audio_sink(nullptr));
}
}
void custom_recorder_impl::handle_audio(const std::string&, const std::string&, const int16_t*, size_t, int, size_t) {
// handle audio frame
}
void custom_recorder_impl::handle_frame(std::unique_ptr<dolbyio::comms::video_frame>) {
// handle raw video frame
}
dolbyio::comms::video_sink_encoded::decoder_config custom_recorder_impl::configure_encoded_sink(const std::string&,
const std::string&) {
// set the codec for encoded video frames
if (vf_ == video_format::ENCODED_OPTIMIZED)
return decoder_config::optimized_decoding;
else
return decoder_config::full_decoding;
}
void custom_recorder_impl::handle_frame_encoded(const std::string&,
std::unique_ptr<dolbyio::comms::encoded_video_frame>) {
// handle encoded video frame
}
dolbyio::comms::video_sink_encoded::decoder_config custom_recorder_impl::decoder_configuration() const {
return vf_ == video_format::ENCODED_OPTIMIZED ? decoder_config::optimized_decoding : decoder_config::full_decoding;
}
dolbyio::comms::video_sink* custom_recorder_impl::video_raw() {
if (vf_ == video_format::YUV)
return this;
return nullptr;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0...3.21)
add_library(custom_recorder STATIC
custom_recorder.h
custom_recorder.cc
)
target_link_libraries(custom_recorder
DolbyioComms::sdk
)
# Enable the deprecated wait
add_compile_definitions(DOLBYIO_COMMS_ENABLE_DEPRECATED_WAIT)