2.2.13. Utility Feeds
2.2.13.1. Overview
A key aspect of SDK feeds are their ability to share audio and video media with other clients or session participants. However, there is a category of feed that we call a utility feed, which is stand-alone and does not require a session. These feeds can be used for a variety of purposes, such as local preview of video input before a session is started.
Utility feeds are created and managed in a similar way to other feeds, but they are
typically created using just feed components, properties and settings, and do not require
a session object like a MediaServerSession to be created.
Utility feeds can use feed stages like any other feed, see the guide section
Feed Stages for more details. SDK releases also include a stages
sample that demonstrates how to create and use stages in utility feeds.
2.2.13.2. Local video feed
UtilityVideoLocalFeed takes a video input/source component (e.g. a webcam) and transfers it to a
video output component (e.g. a window).
The following snippet shows how to create such a utility feed:
PxMedia::UtilityVideoLocalFeed::FeedProperties props("webcam-preview");
PxMedia::VideoInputFeedV4Linux2 input;
PxMedia::VideoOutputFeedAuto output;
auto created = PxMedia::UtilityVideoLocalFeed::create(pxContext, props, input, output);
if (!created) {
// Handle error...
}
auto utilityFeed = created.value();
The feed just takes a regular ProximieContext
(see the ProximieContext guide), and the two input and output video components.
For simplicity we don’t show any additional properties and settings for the components in this example.
Once the feed is created, it is started using startFeed():
auto started = utilityFeed->startFeed();
if (!started) {
// Handle error...
}
Local video utility feeds support start & stop notifications as callbacks:
utilityFeed->onFeedStarted(
[](auto& feed)
{
// Feed has started
});
utilityFeed->onFeedStopped(
[](auto& feed, error_code error)
{
// Feed has stopped, possibly with an error
if (error) {
// Handle error...
}
});
Finally, feeds may be stopped using stopFeed():
auto stopped = utilityFeed->stopFeed();
if (!stopped) {
// Handle error...
}
2.2.13.3. Recording to file
Another utility feed is AVOutputFeedFile, which records
video (and optionally audio) to a file on disk. By default, it uses the X264 software encoder,
but you can provide a custom encoder such as VAAPI for hardware acceleration.
Recording with default X264 encoder
// Create a recording with the default X264 encoder
PxMedia::AVOutputFeedFile::FeedProperties fileProps("recording");
PxMedia::AVOutputFeedFile::AVOutputFeedFileSettings settings;
if (auto err = settings.destinationDirectory("/tmp/recordings")) {
// Handle error...
}
if (auto err = settings.destinationFilenamePattern("video_%02d.mp4")) {
// Handle error...
}
PxMedia::VideoInputFeedV4Linux2 input;
PxMedia::X264EncoderFeedComponent defaultEncoder(
PxMedia::AVOutputFeedFile::defaultRecordingEncoder());
defaultEncoder.bitrate(2000_kbps);
auto recording =
PxMedia::AVOutputFeedFile::create(pxContext, fileProps, settings, input, defaultEncoder);
The defaultRecordingEncoder() helper
function provides a pre-configured X264 encoder with sensible defaults that you can
customize as needed.
Recording with VAAPI hardware encoder
For improved performance on systems with Intel or AMD GPUs, you can use the VAAPI hardware encoder:
// Create a recording with VAAPI hardware encoder for Intel/AMD GPUs
PxMedia::AVOutputFeedFile::FeedProperties filePropsVaapi("recording-vaapi");
PxMedia::AVOutputFeedFile::AVOutputFeedFileSettings settingsVaapi;
if (auto err = settingsVaapi.destinationDirectory("/tmp/recordings")) {
// Handle error...
}
if (auto err = settingsVaapi.destinationFilenamePattern("video_vaapi_%02d.mp4")) {
// Handle error...
}
PxMedia::H264VaapiEncoderComponent vaapiEncoder;
vaapiEncoder.bitrate(2000_kbps);
PxMedia::VideoInputFeedV4Linux2 inputVaapi;
auto recordingVaapi = PxMedia::AVOutputFeedFile::create(
pxContext, filePropsVaapi, settingsVaapi, inputVaapi, vaapiEncoder);
For available encoder properties, see X264EncoderFeedComponent
and H264VaapiEncoderComponent.
2.2.13.4. Local audio feed
UtilityAudioLocalFeed takes one or more audio input/source component (e.g. a microphone) and transfers it to a
audio output component (e.g. a speaker). If it is given multiple inputs they will be mixed together.
Inputs can be added and removed dynamically (after creation and regardless of the play/stop state).
Audio mixing performs format conversion and resampling as necessary.
Local audio feeds are created and managed in a similar way to other feeds.
The following snippet shows how to create a local audio feed:
PxMedia::UtilityAudioLocalFeed::FeedProperties props("audio-mixer");
Proximie::PxMedia::AudioInputFeedTestSignal inputTestSignal;
Proximie::PxMedia::AudioInputFeedAuto inputAuto;
PxMedia::AudioOutputFeedInter outputInter("test-channel");
auto inputInter = outputInter.makeInput();
PxMedia::AudioOutputFeedInter output("test");
auto created = PxMedia::UtilityAudioLocalFeed::create(
pxContext, props, {inputTestSignal, inputInter}, output);
if (!created) {
// Handle error...
}
auto utilityFeed = created.value();
The feed just takes a regular ProximieContext
(see the ProximieContext guide), and 2 input audio components and 1 output
audio component. For simplicity we don’t show any additional properties and settings for the
components in this example.
Once the feed is created, it is started using startFeed():
auto started = utilityFeed->startFeed();
if (!started) {
// Handle error...
}
Local audio feeds support adding and removing inputs dynamically after the feed has been created and while it is playing or not playing:
auto id = utilityFeed->addInput(inputAuto);
if (!id) {
// Handle error...
}
auto removed = utilityFeed->removeInput(id.value());
if (!removed) {
// Handle error...
}
Local audio feeds support start & stop notifications as callbacks:
utilityFeed->onFeedStarted(
[](auto& feed)
{
// Feed has started
});
utilityFeed->onFeedStopped(
[](auto& feed, error_code error)
{
// Feed has stopped, possibly with an error
if (error) {
// Handle error...
}
});
Finally, these feeds may be stopped using stopFeed():
auto stopped = utilityFeed->stopFeed();
if (!stopped) {
// Handle error...
}
All dynamic inputs (those added using addInput())
will be removed when the local audio feed is stopped.