Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit 00f08f4

Browse files
authored
Add volume and document to active audio event (#1021)
1 parent 58889a2 commit 00f08f4

File tree

6 files changed

+71
-9
lines changed

6 files changed

+71
-9
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
| OWT Active Audio Stream Introduction |
2+
3+
4+
# Overview
5+
6+
OWT conference provide functionality to select K (K = 3 by default) most active audio streams in the conference.
7+
8+
# How to enable
9+
The active audio selecting feature can be enabled by setting `selectActiveAudio` to true in room configuration. When it's enabled, an audio node will be used for selecting audio streams for each room, and K audio-only streams will be produced as most active audio streams in the conference.
10+
11+
# Stream
12+
```
13+
stream.info = {
14+
type: 'selecting',
15+
owner: 'unknown' | string(ParticipantId),
16+
activeInput: 'unknown' | string(StreamId),
17+
}
18+
```
19+
20+
# Events
21+
Stream notification for input change of active audio stream.
22+
```
23+
{
24+
id: activeAudioId,
25+
status: 'update',
26+
data: {field: 'activeInput', value: {id: originInput, volume: 'major' | 'minor'}}
27+
}
28+
```
29+

source/agent/audio/activeAudioSelector.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ActiveAudioSelector extends EventEmitter {
3131
this.ranker.addOutput(this.topK[i]);
3232
}
3333
this.currentRank = Array(k).fill('');
34+
this.currentVolume = Array(k).fill('');
3435
log.debug('Init with K:', k);
3536
}
3637

@@ -55,6 +56,15 @@ class ActiveAudioSelector extends EventEmitter {
5556
log.warn('Unknown stream ID', streamId);
5657
}
5758
pendingAddIndexes.push(i);
59+
} else if (this.currentVolume[i] !== changes[i][1]) {
60+
let streamId = this.currentRank[i];
61+
if (this.inputs.has(streamId)) {
62+
let { owner, codec } = this.inputs.get(streamId);
63+
const volume = changes[i][1];
64+
log.debug('Volume change:', streamId, volume);
65+
this.emit('source-change',
66+
i, owner, streamId, codec, volume);
67+
}
5868
}
5969
}
6070
for (let i of pendingAddIndexes) {
@@ -63,12 +73,14 @@ class ActiveAudioSelector extends EventEmitter {
6373
if (this.inputs.has(streamId)) {
6474
let { owner, codec } = this.inputs.get(streamId);
6575
log.debug('Active input:', owner, streamId, codec, i);
66-
this.emit('source-change', i, owner, streamId, codec);
76+
const volume = changes[i][1];
77+
this.emit('source-change', i, owner, streamId, codec, volume);
6778
} else if (streamId !== '') {
6879
log.warn('Unknown stream ID', streamId);
6980
}
7081
}
7182
this.currentRank = changes.map(pair => pair[0]);
83+
this.currentVolume = changes.map(pair => pair[1]);
7284
}
7385

7486
addInput(owner, streamId, codec, conn) {

source/agent/audio/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ module.exports = function (rpcClient, selfRpcId, parentRpcId, clusterWorkerIP) {
138138
return;
139139
}
140140
const selector = new ActiveAudioSelector(activeStreamIds.length);
141-
selector.on('source-change', (i, owner, streamId, codec) => {
141+
selector.on('source-change', (i, owner, streamId, codec, volume) => {
142142
// Notify controller
143-
const target = {id: activeStreamIds[i], owner, codec};
143+
const target = {id: activeStreamIds[i], owner, codec, volume};
144144
ctrlr && rpcClient.remoteCall(ctrlr, 'onAudioActiveness',
145145
[belongToRoom, streamId, target],
146146
{callback: function(){}});

source/agent/conference/conference.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,12 +1927,18 @@ var Conference = function (rpcClient, selfRpcId) {
19271927
activeInputStream : trackOwners[activeInputStream];
19281928
const activeAudioId = target.id;
19291929
if (streams[activeAudioId] instanceof SelectedStream) {
1930-
if (streams[activeAudioId].info.activeInput !== input) {
1930+
if (streams[activeAudioId].info.activeInput !== input ||
1931+
streams[activeAudioId].info.volume !== target.volume) {
19311932
streams[activeAudioId].info.activeInput = input;
19321933
streams[activeAudioId].info.activeOwner = target.owner;
1933-
room_config.notifying.streamChange &&
1934-
sendMsg('room', 'all', 'stream',
1935-
{id: activeAudioId, status: 'update', data: {field: 'activeInput', value: input}});
1934+
streams[activeAudioId].info.volume = target.volume;
1935+
//TODO: separate major and activeInput when notifying
1936+
room_config.notifying.streamChange && sendMsg('room', 'all', 'stream',
1937+
{
1938+
id: activeAudioId,
1939+
status: 'update',
1940+
data: {field: 'activeInput', value: {id: input, volume: target.volume}}
1941+
});
19361942
}
19371943
}
19381944
callback('callback', 'ok');

source/agent/conference/stream.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
* stream: string(StreamId),
4141
* region: object(Region)
4242
* }]
43+
* } | object(SelectInfo):: {
44+
* owner: string(ParticipantId),
45+
* type: 'selecting',
46+
* activeInput: 'unknown' | string(StreamId),
47+
* volume: 'major' | 'minor' | undefined,
4348
* }
4449
* }
4550
*/

source/core/owt_base/selector/AudioRanker.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,17 @@ void AudioRanker::updateInputInternal(std::string streamId, int level, bool trig
160160
}
161161

162162
if (inTopK && level != audioProc->iter()->first) {
163+
ELOG_DEBUG("Top K internal change: %s %s",
164+
audioProc->streamId().c_str(), audioProc->ownerId().c_str());
165+
auto oldUp = m_topK.upper_bound(audioProc->iter()->first);
163166
m_topK.erase(audioProc->iter());
164167
auto newIt = m_topK.emplace(level, audioProc);
165168
audioProc->setIter(newIt);
169+
auto newUp = m_topK.upper_bound(level);
170+
if (oldUp != newUp && triggerChange) {
171+
ELOG_DEBUG("Top K internal trigger");
172+
triggerRankChange();
173+
}
166174
}
167175
} else {
168176
// Previous in others, check if it's still in
@@ -241,14 +249,16 @@ void AudioRanker::triggerRankChange()
241249
}
242250
}
243251

252+
size_t order = 0;
244253
for (auto& pair : m_topK) {
254+
order++;
245255
auto audioProc = pair.second;
246256
FrameDestination* output = audioProc->linkedOutput();
247257
int index = m_outputIndexes[output];
248258
ELOG_DEBUG("update output index: %d, streamId: %s",
249259
index, audioProc->streamId().c_str());
250260
updates[index].first = audioProc->streamId();
251-
updates[index].second = audioProc->ownerId();
261+
updates[index].second = (order == m_topK.size() ? "major" : "minor");
252262
}
253263

254264
bool hasChange = false;
@@ -338,7 +348,7 @@ void AudioRanker::AudioLevelProcessor::onFeedback(const FeedbackMsg& msg)
338348

339349
void AudioRanker::AudioLevelProcessor::deliverOwnerData()
340350
{
341-
ELOG_DEBUG("deliver ownerID as metadata");
351+
ELOG_DEBUG("deliver ownerID as metadata %s", m_ownerId.c_str());
342352
// Pass owner ID metadata to linkedoutput
343353
MetaData ownerData;
344354
ownerData.type = META_DATA_OWNER_ID;

0 commit comments

Comments
 (0)