The Virtual Tracks feature lets you create audio tracks that span file boundaries. Normally an audio track is mapped to a single audio file:
When using Virtual Tracks the one-to-one mapping is replaced with a one-to-many mapping:
This allows audio tracks to contain channels from one or more audio files. This is useful since the browsers (at the time of writing) have a limitation that only allows a single (1) stream of audio with a maximum of 8 channels.
Using virtual tracks makes it possible to ingest multi-channel audio files that in reality include several audio tracks and use Validate to determine the audio track boundaries within the multi-channel file. The multi-channel file would in this case be split into <= 8 channel files, during ingest for example, to allow playback in the browser and Validate would show these files as a single audio track. To help determine the audio track boundaries you can configure Audio Profiles which you can use in Validate to classify the content. In turn, the profile can be used to trigger a transcode job to extract the audio tracks from the multi-channel file.
The virtual tracks feature is enabled by setting apps.validate.features.virtualTracks
to true in settings.js
.
apps: {
validate: {
features: {
virtualTracks: true,
}
}
}
Read more about Validate Settings
Audio profiles are used to describe a track layout in a multi-channel audio file, as seen in the image below. A 10 channel file may contain: two stereo tracks followed by a 5.1 surround track; or 5 stereo tracks; or a 7.1 surround track followed by two mono tracks; or any other combination. The audio profiles define these different layouts.
Here is an example of how to configure these 3 profiles in Validate:
apps: {
validate: {
audioTracks: [
{
id: "mono",
name: "Mono",
channelCount: 1,
channelNames: ["C"],
},
{
id: "stereo",
name: "Stereo",
channelCount: 2,
channelNames: ["L", "R"],
},
{
id: "surround51",
name: "5.1 Surround",
channelCount: 6,
channelNames: ["L", "R", "C", "LFE", "Ls", "Rs"],
},
{
id: "surround71",
name: "7.1 Surround",
channelCount: 8,
channelNames: ["L", "R", "C", "LFE", "LsS", "RsS", "LsR", "RsR"],
},
],
audioProfiles: [
{
id: "1",
name: "Audio Profile 1",
tracks: ["stereo", "stereo", "surround51"],
},
{
id: "2",
name: "Audio Profile 2",
tracks: ["stereo", "stereo", "stereo", "stereo", "stereo"],
},
{
id: "3",
name: "Audio Profile 3",
tracks: ["surround71", "mono", "mono"],
},
],
},
}
Read more about how to configure Audio Profiles in Validate Settings
When applying a profile, in order to get the same result on the generated proxies of the original multi-channel file, the order of the proxies matters. Setting the av:order
metadata field on the files makes it possible to control the order of the proxies. If no av:order
metadata exists on the files they will be ordered by their id
. It's also possible to change what field to use for ordering by changing the metadata key apps.validate.virtualTracksFileOrderMetadataKey
in Validate Settings.
apps: {
validate: {
virtualTracksFileOrderMetadataKey: "av:order",
}
}
Virtual tracks data is stored as Asset metadata when a profile is saved. The profile id is stored under the key av:profile
, and the virtual track data is stored as JSON in av:virtual_tracks
by default. The keys can be changed in settings.js
:
apps: {
validate: {
profileMetadataKey: "av:profile",
virtualTracksMetadataKey: "av:virtual_tracks",
}
}
The virtual tracks JSON data contains information about the channel mappings as well as metadata about the tracks, like language for example. Here's an example:
[
{
"id": "v-0",
"label": "Audio 1",
"subLabel": "Stereo",
"language": "en",
"channels": [
{ "sourceFileId": "43", "sourceChannelIndex": 0, "sourceStreamIndex": 0 },
{ "sourceFileId": "43", "sourceChannelIndex": 1, "sourceStreamIndex": 0 },
],
},
{
"id": "v-1",
"label": "Audio 2",
"subLabel": "Stereo",
"language": "es",
"channels": [
{ "sourceFileId": "43", "sourceChannelIndex": 2, "sourceStreamIndex": 0 },
{ "sourceFileId": "43", "sourceChannelIndex": 3, "sourceStreamIndex": 0 },
],
},
{
"id": "v-2",
"label": "Audio 3",
"subLabel": "5.1 Surround",
"language": "it",
"channels": [
{ "sourceFileId": "43", "sourceChannelIndex": 4, "sourceStreamIndex": 0 },
{ "sourceFileId": "43", "sourceChannelIndex": 5, "sourceStreamIndex": 0 },
{ "sourceFileId": "43", "sourceChannelIndex": 6, "sourceStreamIndex": 0 },
{ "sourceFileId": "43", "sourceChannelIndex": 7, "sourceStreamIndex": 0 },
{ "sourceFileId": "44", "sourceChannelIndex": 0, "sourceStreamIndex": 0 },
{ "sourceFileId": "44", "sourceChannelIndex": 1, "sourceStreamIndex": 0 },
],
},
]
Below is a description of the keys found in the JSON structure:
id
Id of the audio track, internal id used by Validate.
label
The label of the audio track. Currently this is set by Validate.
subLabel
The sub label. This label is set to the audio profile label.
language
The language set on the track.
channels
The source file channel mapping. Further explained below.
channels.sourceFileId
The source file id (of the proxy containing the channel).
channels.sourceStreamIndex
The source file stream index of the channel (for now this will always be 0 since browsers only support playing the first audio stream).
channels.sourceChannelIndex
The source file channel index.
Proxy files need to have channelCount
set in the audio stream metadata for this feature to work. Currently we have no way to determine the channel count in the frontend for all audio files.
We recommend that you serve the proxies using HTTP2 to avoid browser limitations that limit the maximum number of concurrent connections. Multiple discrete audio files are streamed at the same time when using this feature making it easy to hit the roof of maximum number of connections. This is specifically related to HTTP 1.1, so using HTTP2 avoids this problem altogether.
Since profiles and virtual tracks data is stored in the asset metadata the user needs to have the metadata.write
role to be able to set profiles. Similarly, users need to have metadata.read
to be able to read and load virtual tracks. More about how to configure Roles and Permissions here.