mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: hark refactoring. Allow PublisherSpeakingEvent for local streams
parent
0a3553c704
commit
87117f31e4
|
@ -51,7 +51,7 @@ let platform: PlatformUtils;
|
||||||
* - accessDialogClosed
|
* - accessDialogClosed
|
||||||
* - streamCreated ([[StreamEvent]])
|
* - streamCreated ([[StreamEvent]])
|
||||||
* - streamDestroyed ([[StreamEvent]])
|
* - streamDestroyed ([[StreamEvent]])
|
||||||
* - streamPropertyChanged ([[StreamPropertyChangedEvent]])
|
* - _All events inherited from [[StreamManager]] class_
|
||||||
*/
|
*/
|
||||||
export class Publisher extends StreamManager {
|
export class Publisher extends StreamManager {
|
||||||
|
|
||||||
|
|
|
@ -120,22 +120,6 @@ export class Session extends EventDispatcher {
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
options: SessionOptions;
|
options: SessionOptions;
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
startSpeakingEventsEnabled = false;
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
startSpeakingEventsEnabledOnce = false;
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
stopSpeakingEventsEnabled = false;
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
stopSpeakingEventsEnabledOnce = false;
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
|
@ -655,22 +639,28 @@ export class Session extends EventDispatcher {
|
||||||
super.onAux(type, "Event '" + type + "' triggered by 'Session'", handler);
|
super.onAux(type, "Event '" + type + "' triggered by 'Session'", handler);
|
||||||
|
|
||||||
if (type === 'publisherStartSpeaking') {
|
if (type === 'publisherStartSpeaking') {
|
||||||
this.startSpeakingEventsEnabled = true;
|
// If there are already available remote streams with audio, enable hark 'speaking' event in all of them
|
||||||
// If there are already available remote streams, enable hark 'speaking' event in all of them
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream && remoteConnection.stream.hasAudio) {
|
if (!!remoteConnection.stream?.hasAudio) {
|
||||||
remoteConnection.stream.enableStartSpeakingEvent();
|
remoteConnection.stream.enableHarkSpeakingEvent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.hasAudio) {
|
||||||
|
// If connected to the Session and publishing with audio, also enable hark 'speaking' event for the Publisher
|
||||||
|
this.connection.stream.enableHarkSpeakingEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type === 'publisherStopSpeaking') {
|
if (type === 'publisherStopSpeaking') {
|
||||||
this.stopSpeakingEventsEnabled = true;
|
// If there are already available remote streams with audio, enable hark 'stopped_speaking' event in all of them
|
||||||
// If there are already available remote streams, enable hark 'stopped_speaking' event in all of them
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream && remoteConnection.stream.hasAudio) {
|
if (!!remoteConnection.stream?.hasAudio) {
|
||||||
remoteConnection.stream.enableStopSpeakingEvent();
|
remoteConnection.stream.enableHarkStoppedSpeakingEvent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.hasAudio) {
|
||||||
|
// If connected to the Session and publishing with audio, also enable hark 'stopped_speaking' event for the Publisher
|
||||||
|
this.connection.stream.enableHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -685,22 +675,28 @@ export class Session extends EventDispatcher {
|
||||||
super.onceAux(type, "Event '" + type + "' triggered once by 'Session'", handler);
|
super.onceAux(type, "Event '" + type + "' triggered once by 'Session'", handler);
|
||||||
|
|
||||||
if (type === 'publisherStartSpeaking') {
|
if (type === 'publisherStartSpeaking') {
|
||||||
this.startSpeakingEventsEnabledOnce = true;
|
// If there are already available remote streams with audio, enable hark 'speaking' event (once) in all of them once
|
||||||
// If there are already available remote streams, enable hark 'speaking' event in all of them once
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream && remoteConnection.stream.hasAudio) {
|
if (!!remoteConnection.stream?.hasAudio) {
|
||||||
remoteConnection.stream.enableOnceStartSpeakingEvent();
|
remoteConnection.stream.enableOnceHarkSpeakingEvent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.hasAudio) {
|
||||||
|
// If connected to the Session and publishing with audio, also enable hark 'speaking' event (once) for the Publisher
|
||||||
|
this.connection.stream.enableOnceHarkSpeakingEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type === 'publisherStopSpeaking') {
|
if (type === 'publisherStopSpeaking') {
|
||||||
this.stopSpeakingEventsEnabledOnce = true;
|
// If there are already available remote streams with audio, enable hark 'stopped_speaking' event (once) in all of them once
|
||||||
// If there are already available remote streams, enable hark 'stopped_speaking' event in all of them once
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream && remoteConnection.stream.hasAudio) {
|
if (!!remoteConnection.stream?.hasAudio) {
|
||||||
remoteConnection.stream.enableOnceStopSpeakingEvent();
|
remoteConnection.stream.enableOnceHarkStoppedSpeakingEvent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.hasAudio) {
|
||||||
|
// If connected to the Session and publishing with audio, also enable hark 'stopped_speaking' event (once) for the Publisher
|
||||||
|
this.connection.stream.enableOnceHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -715,27 +711,41 @@ export class Session extends EventDispatcher {
|
||||||
super.off(type, handler);
|
super.off(type, handler);
|
||||||
|
|
||||||
if (type === 'publisherStartSpeaking') {
|
if (type === 'publisherStartSpeaking') {
|
||||||
let remainingStartSpeakingListeners = this.ee.getListeners(type).length;
|
// Check if Session object still has some listener for the event
|
||||||
if (remainingStartSpeakingListeners === 0) {
|
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false)) {
|
||||||
this.startSpeakingEventsEnabled = false;
|
|
||||||
// If there are already available remote streams, disable hark in all of them
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream) {
|
if (!!remoteConnection.stream?.streamManager) {
|
||||||
remoteConnection.stream.disableStartSpeakingEvent(false);
|
// Check if Subscriber object still has some listener for the event
|
||||||
|
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, remoteConnection.stream.streamManager)) {
|
||||||
|
remoteConnection.stream.disableHarkSpeakingEvent(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.streamManager) {
|
||||||
|
// Check if Publisher object still has some listener for the event
|
||||||
|
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.connection.stream.streamManager)) {
|
||||||
|
this.connection.stream.disableHarkSpeakingEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type === 'publisherStopSpeaking') {
|
if (type === 'publisherStopSpeaking') {
|
||||||
let remainingStopSpeakingListeners = this.ee.getListeners(type).length;
|
// Check if Session object still has some listener for the event
|
||||||
if (remainingStopSpeakingListeners === 0) {
|
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false)) {
|
||||||
this.stopSpeakingEventsEnabled = false;
|
|
||||||
// If there are already available remote streams, disable hark in all of them
|
|
||||||
this.remoteConnections.forEach(remoteConnection => {
|
this.remoteConnections.forEach(remoteConnection => {
|
||||||
if (!!remoteConnection.stream) {
|
if (!!remoteConnection.stream?.streamManager) {
|
||||||
remoteConnection.stream.disableStopSpeakingEvent(false);
|
// Check if Subscriber object still has some listener for the event
|
||||||
|
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, remoteConnection.stream.streamManager)) {
|
||||||
|
remoteConnection.stream.disableHarkStoppedSpeakingEvent(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!!this.connection?.stream?.streamManager) {
|
||||||
|
// Check if Publisher object still has some listener for the event
|
||||||
|
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.connection.stream.streamManager)) {
|
||||||
|
this.connection.stream.disableHarkStoppedSpeakingEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -1271,6 +1281,27 @@ export class Session extends EventDispatcher {
|
||||||
return new OpenViduError(OpenViduErrorName.OPENVIDU_NOT_CONNECTED, "There is no connection to the session. Method 'Session.connect' must be successfully completed first");
|
return new OpenViduError(OpenViduErrorName.OPENVIDU_NOT_CONNECTED, "There is no connection to the session. Method 'Session.connect' must be successfully completed first");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
anySpeechEventListenerEnabled(event: string, onlyOnce: boolean, streamManager?: StreamManager): boolean {
|
||||||
|
let handlersInSession = this.ee.getListeners(event);
|
||||||
|
if (onlyOnce) {
|
||||||
|
handlersInSession = handlersInSession.filter(h => (h as any).once);
|
||||||
|
}
|
||||||
|
let listenersInSession = handlersInSession.length;
|
||||||
|
if (listenersInSession > 0) return true;
|
||||||
|
let listenersInStreamManager = 0;
|
||||||
|
if (!!streamManager) {
|
||||||
|
let handlersInStreamManager = streamManager.ee.getListeners(event);
|
||||||
|
if (onlyOnce) {
|
||||||
|
handlersInStreamManager = handlersInStreamManager.filter(h => (h as any).once);
|
||||||
|
}
|
||||||
|
listenersInStreamManager = handlersInStreamManager.length;
|
||||||
|
}
|
||||||
|
return listenersInStreamManager > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Private methods */
|
/* Private methods */
|
||||||
|
|
||||||
private connectAux(token: string): Promise<void> {
|
private connectAux(token: string): Promise<void> {
|
||||||
|
|
|
@ -181,27 +181,27 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
publisherStartSpeakingEventEnabled = false;
|
harkSpeakingEnabled = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
publisherStartSpeakingEventEnabledOnce = false;
|
harkSpeakingEnabledOnce = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
publisherStopSpeakingEventEnabled = false;
|
harkStoppedSpeakingEnabled = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
publisherStopSpeakingEventEnabledOnce = false;
|
harkStoppedSpeakingEnabledOnce = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
volumeChangeEventEnabled = false;
|
harkVolumeChangeEnabled = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
volumeChangeEventEnabledOnce = false;
|
harkVolumeChangeEnabledOnce = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
|
@ -540,13 +540,14 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableStartSpeakingEvent(): void {
|
enableHarkSpeakingEvent(): void {
|
||||||
this.setSpeechEventIfNotExists();
|
this.setHarkListenerIfNotExists();
|
||||||
if (!this.publisherStartSpeakingEventEnabled) {
|
if (!this.harkSpeakingEnabled) {
|
||||||
this.publisherStartSpeakingEventEnabled = true;
|
this.harkSpeakingEnabled = true;
|
||||||
this.speechEvent.on('speaking', () => {
|
this.speechEvent.on('speaking', () => {
|
||||||
this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
||||||
this.publisherStartSpeakingEventEnabledOnce = false; // Disable 'once' version if 'on' version was triggered
|
this.streamManager.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.streamManager, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
||||||
|
this.harkSpeakingEnabledOnce = false; // Disable 'once' version if 'on' version was triggered
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,16 +555,17 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableOnceStartSpeakingEvent(): void {
|
enableOnceHarkSpeakingEvent(): void {
|
||||||
this.setSpeechEventIfNotExists();
|
this.setHarkListenerIfNotExists();
|
||||||
if (!this.publisherStartSpeakingEventEnabledOnce) {
|
if (!this.harkSpeakingEnabledOnce) {
|
||||||
this.publisherStartSpeakingEventEnabledOnce = true;
|
this.harkSpeakingEnabledOnce = true;
|
||||||
this.speechEvent.once('speaking', () => {
|
this.speechEvent.once('speaking', () => {
|
||||||
if (this.publisherStartSpeakingEventEnabledOnce) {
|
if (this.harkSpeakingEnabledOnce) {
|
||||||
// If the listener has been disabled in the meantime (for example by the 'on' version) do not trigger the event
|
// If the listener has been disabled in the meantime (for example by the 'on' version) do not trigger the event
|
||||||
this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
||||||
|
this.streamManager.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent(this.streamManager, 'publisherStartSpeaking', this.connection, this.streamId)]);
|
||||||
}
|
}
|
||||||
this.disableStartSpeakingEvent(true);
|
this.disableHarkSpeakingEvent(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,22 +573,22 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
disableStartSpeakingEvent(disabledByOnce: boolean): void {
|
disableHarkSpeakingEvent(disabledByOnce: boolean): void {
|
||||||
if (!!this.speechEvent) {
|
if (!!this.speechEvent) {
|
||||||
this.publisherStartSpeakingEventEnabledOnce = false;
|
this.harkSpeakingEnabledOnce = false;
|
||||||
if (disabledByOnce) {
|
if (disabledByOnce) {
|
||||||
if (this.publisherStartSpeakingEventEnabled) {
|
if (this.harkSpeakingEnabled) {
|
||||||
// The 'on' version of this same event is enabled too. Do not remove the hark listener
|
// The 'on' version of this same event is enabled too. Do not remove the hark listener
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.publisherStartSpeakingEventEnabled = false;
|
this.harkSpeakingEnabled = false;
|
||||||
}
|
}
|
||||||
// Shutting down the hark event
|
// Shutting down the hark event
|
||||||
if (this.volumeChangeEventEnabled ||
|
if (this.harkVolumeChangeEnabled ||
|
||||||
this.volumeChangeEventEnabledOnce ||
|
this.harkVolumeChangeEnabledOnce ||
|
||||||
this.publisherStopSpeakingEventEnabled ||
|
this.harkStoppedSpeakingEnabled ||
|
||||||
this.publisherStopSpeakingEventEnabledOnce) {
|
this.harkStoppedSpeakingEnabledOnce) {
|
||||||
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
||||||
this.speechEvent.off('speaking');
|
this.speechEvent.off('speaking');
|
||||||
} else {
|
} else {
|
||||||
|
@ -600,13 +602,14 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableStopSpeakingEvent(): void {
|
enableHarkStoppedSpeakingEvent(): void {
|
||||||
this.setSpeechEventIfNotExists();
|
this.setHarkListenerIfNotExists();
|
||||||
if (!this.publisherStopSpeakingEventEnabled) {
|
if (!this.harkStoppedSpeakingEnabled) {
|
||||||
this.publisherStopSpeakingEventEnabled = true;
|
this.harkStoppedSpeakingEnabled = true;
|
||||||
this.speechEvent.on('stopped_speaking', () => {
|
this.speechEvent.on('stopped_speaking', () => {
|
||||||
this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
||||||
this.publisherStopSpeakingEventEnabledOnce = false; // Disable 'once' version if 'on' version was triggered
|
this.streamManager.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.streamManager, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
||||||
|
this.harkStoppedSpeakingEnabledOnce = false; // Disable 'once' version if 'on' version was triggered
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,16 +617,17 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableOnceStopSpeakingEvent(): void {
|
enableOnceHarkStoppedSpeakingEvent(): void {
|
||||||
this.setSpeechEventIfNotExists();
|
this.setHarkListenerIfNotExists();
|
||||||
if (!this.publisherStopSpeakingEventEnabledOnce) {
|
if (!this.harkStoppedSpeakingEnabledOnce) {
|
||||||
this.publisherStopSpeakingEventEnabledOnce = true;
|
this.harkStoppedSpeakingEnabledOnce = true;
|
||||||
this.speechEvent.once('stopped_speaking', () => {
|
this.speechEvent.once('stopped_speaking', () => {
|
||||||
if (this.publisherStopSpeakingEventEnabledOnce) {
|
if (this.harkStoppedSpeakingEnabledOnce) {
|
||||||
// If the listener has been disabled in the meantime (for example by the 'on' version) do not trigger the event
|
// If the listener has been disabled in the meantime (for example by the 'on' version) do not trigger the event
|
||||||
this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.session, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
||||||
|
this.streamManager.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent(this.streamManager, 'publisherStopSpeaking', this.connection, this.streamId)]);
|
||||||
}
|
}
|
||||||
this.disableStopSpeakingEvent(true);
|
this.disableHarkStoppedSpeakingEvent(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,23 +635,23 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
disableStopSpeakingEvent(disabledByOnce: boolean): void {
|
disableHarkStoppedSpeakingEvent(disabledByOnce: boolean): void {
|
||||||
if (!!this.speechEvent) {
|
if (!!this.speechEvent) {
|
||||||
this.publisherStopSpeakingEventEnabledOnce = false;
|
this.harkStoppedSpeakingEnabledOnce = false;
|
||||||
if (disabledByOnce) {
|
if (disabledByOnce) {
|
||||||
if (this.publisherStopSpeakingEventEnabled) {
|
if (this.harkStoppedSpeakingEnabled) {
|
||||||
// We are cancelling the 'once' listener for this event, but the 'on' version
|
// We are cancelling the 'once' listener for this event, but the 'on' version
|
||||||
// of this same event is enabled too. Do not remove the hark listener
|
// of this same event is enabled too. Do not remove the hark listener
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.publisherStopSpeakingEventEnabled = false;
|
this.harkStoppedSpeakingEnabled = false;
|
||||||
}
|
}
|
||||||
// Shutting down the hark event
|
// Shutting down the hark event
|
||||||
if (this.volumeChangeEventEnabled ||
|
if (this.harkVolumeChangeEnabled ||
|
||||||
this.volumeChangeEventEnabledOnce ||
|
this.harkVolumeChangeEnabledOnce ||
|
||||||
this.publisherStartSpeakingEventEnabled ||
|
this.harkSpeakingEnabled ||
|
||||||
this.publisherStartSpeakingEventEnabledOnce) {
|
this.harkSpeakingEnabledOnce) {
|
||||||
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
||||||
this.speechEvent.off('stopped_speaking');
|
this.speechEvent.off('stopped_speaking');
|
||||||
} else {
|
} else {
|
||||||
|
@ -661,10 +665,10 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableVolumeChangeEvent(force: boolean): void {
|
enableHarkVolumeChangeEvent(force: boolean): void {
|
||||||
if (this.setSpeechEventIfNotExists()) {
|
if (this.setHarkListenerIfNotExists()) {
|
||||||
if (!this.volumeChangeEventEnabled || force) {
|
if (!this.harkVolumeChangeEnabled || force) {
|
||||||
this.volumeChangeEventEnabled = true;
|
this.harkVolumeChangeEnabled = true;
|
||||||
this.speechEvent.on('volume_change', harkEvent => {
|
this.speechEvent.on('volume_change', harkEvent => {
|
||||||
const oldValue = this.speechEvent.oldVolumeValue;
|
const oldValue = this.speechEvent.oldVolumeValue;
|
||||||
const value = { newValue: harkEvent, oldValue };
|
const value = { newValue: harkEvent, oldValue };
|
||||||
|
@ -674,51 +678,51 @@ export class Stream {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This way whenever the MediaStream object is available, the event listener will be automatically added
|
// This way whenever the MediaStream object is available, the event listener will be automatically added
|
||||||
this.volumeChangeEventEnabled = true;
|
this.harkVolumeChangeEnabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableOnceVolumeChangeEvent(force: boolean): void {
|
enableOnceHarkVolumeChangeEvent(force: boolean): void {
|
||||||
if (this.setSpeechEventIfNotExists()) {
|
if (this.setHarkListenerIfNotExists()) {
|
||||||
if (!this.volumeChangeEventEnabledOnce || force) {
|
if (!this.harkVolumeChangeEnabledOnce || force) {
|
||||||
this.volumeChangeEventEnabledOnce = true;
|
this.harkVolumeChangeEnabledOnce = true;
|
||||||
this.speechEvent.once('volume_change', harkEvent => {
|
this.speechEvent.once('volume_change', harkEvent => {
|
||||||
const oldValue = this.speechEvent.oldVolumeValue;
|
const oldValue = this.speechEvent.oldVolumeValue;
|
||||||
const value = { newValue: harkEvent, oldValue };
|
const value = { newValue: harkEvent, oldValue };
|
||||||
this.speechEvent.oldVolumeValue = harkEvent;
|
this.speechEvent.oldVolumeValue = harkEvent;
|
||||||
this.disableVolumeChangeEvent(true);
|
this.disableHarkVolumeChangeEvent(true);
|
||||||
this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent(this.streamManager, 'streamAudioVolumeChange', value)]);
|
this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent(this.streamManager, 'streamAudioVolumeChange', value)]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This way whenever the MediaStream object is available, the event listener will be automatically added
|
// This way whenever the MediaStream object is available, the event listener will be automatically added
|
||||||
this.volumeChangeEventEnabledOnce = true;
|
this.harkVolumeChangeEnabledOnce = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
disableVolumeChangeEvent(disabledByOnce: boolean): void {
|
disableHarkVolumeChangeEvent(disabledByOnce: boolean): void {
|
||||||
if (!!this.speechEvent) {
|
if (!!this.speechEvent) {
|
||||||
this.volumeChangeEventEnabledOnce = false;
|
this.harkVolumeChangeEnabledOnce = false;
|
||||||
if (disabledByOnce) {
|
if (disabledByOnce) {
|
||||||
if (this.volumeChangeEventEnabled) {
|
if (this.harkVolumeChangeEnabled) {
|
||||||
// We are cancelling the 'once' listener for this event, but the 'on' version
|
// We are cancelling the 'once' listener for this event, but the 'on' version
|
||||||
// of this same event is enabled too. Do not remove the hark listener
|
// of this same event is enabled too. Do not remove the hark listener
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.volumeChangeEventEnabled = false;
|
this.harkVolumeChangeEnabled = false;
|
||||||
}
|
}
|
||||||
// Shutting down the hark event
|
// Shutting down the hark event
|
||||||
if (this.publisherStartSpeakingEventEnabled ||
|
if (this.harkSpeakingEnabled ||
|
||||||
this.publisherStartSpeakingEventEnabledOnce ||
|
this.harkSpeakingEnabledOnce ||
|
||||||
this.publisherStopSpeakingEventEnabled ||
|
this.harkStoppedSpeakingEnabled ||
|
||||||
this.publisherStopSpeakingEventEnabledOnce) {
|
this.harkStoppedSpeakingEnabledOnce) {
|
||||||
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
// Some other hark event is enabled. Cannot stop the hark process, just remove the specific listener
|
||||||
this.speechEvent.off('volume_change');
|
this.speechEvent.off('volume_change');
|
||||||
} else {
|
} else {
|
||||||
|
@ -779,7 +783,7 @@ export class Stream {
|
||||||
|
|
||||||
/* Private methods */
|
/* Private methods */
|
||||||
|
|
||||||
private setSpeechEventIfNotExists(): boolean {
|
private setHarkListenerIfNotExists(): boolean {
|
||||||
if (!!this.mediaStream) {
|
if (!!this.mediaStream) {
|
||||||
if (!this.speechEvent) {
|
if (!this.speechEvent) {
|
||||||
const harkOptions = !!this.harkOptions ? this.harkOptions : (this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {});
|
const harkOptions = !!this.harkOptions ? this.harkOptions : (this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {});
|
||||||
|
@ -1026,27 +1030,23 @@ export class Stream {
|
||||||
private initHarkEvents(): void {
|
private initHarkEvents(): void {
|
||||||
if (!!this.mediaStream!.getAudioTracks()[0]) {
|
if (!!this.mediaStream!.getAudioTracks()[0]) {
|
||||||
// Hark events can only be set if audio track is available
|
// Hark events can only be set if audio track is available
|
||||||
if (this.streamManager.remote) {
|
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', true, this.streamManager)) {
|
||||||
// publisherStartSpeaking/publisherStopSpeaking is only defined for remote streams
|
this.enableOnceHarkSpeakingEvent();
|
||||||
if (this.session.startSpeakingEventsEnabled) {
|
|
||||||
this.enableStartSpeakingEvent();
|
|
||||||
}
|
|
||||||
if (this.session.startSpeakingEventsEnabledOnce) {
|
|
||||||
this.enableOnceStartSpeakingEvent();
|
|
||||||
}
|
|
||||||
if (this.session.stopSpeakingEventsEnabled) {
|
|
||||||
this.enableStopSpeakingEvent();
|
|
||||||
}
|
|
||||||
if (this.session.stopSpeakingEventsEnabledOnce) {
|
|
||||||
this.enableOnceStopSpeakingEvent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// streamAudioVolumeChange event is defined for both Publishers and Subscribers
|
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.streamManager)) {
|
||||||
if (this.volumeChangeEventEnabled) {
|
this.enableHarkSpeakingEvent();
|
||||||
this.enableVolumeChangeEvent(true);
|
|
||||||
}
|
}
|
||||||
if (this.volumeChangeEventEnabledOnce) {
|
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', true, this.streamManager)) {
|
||||||
this.enableOnceVolumeChangeEvent(true);
|
this.enableOnceHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.streamManager)) {
|
||||||
|
this.enableHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (this.harkVolumeChangeEnabledOnce) {
|
||||||
|
this.enableOnceHarkVolumeChangeEvent(true);
|
||||||
|
}
|
||||||
|
if (this.harkVolumeChangeEnabled) {
|
||||||
|
this.enableHarkVolumeChangeEvent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ let platform: PlatformUtils;
|
||||||
* - videoElementCreated ([[VideoElementEvent]])
|
* - videoElementCreated ([[VideoElementEvent]])
|
||||||
* - videoElementDestroyed ([[VideoElementEvent]])
|
* - videoElementDestroyed ([[VideoElementEvent]])
|
||||||
* - streamPlaying ([[StreamManagerEvent]])
|
* - streamPlaying ([[StreamManagerEvent]])
|
||||||
|
* - streamPropertyChanged ([[StreamPropertyChangedEvent]])
|
||||||
|
* - publisherStartSpeaking ([[PublisherSpeakingEvent]])
|
||||||
|
* - publisherStopSpeaking ([[PublisherSpeakingEvent]])
|
||||||
* - streamAudioVolumeChange ([[StreamManagerEvent]])
|
* - streamAudioVolumeChange ([[StreamManagerEvent]])
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -174,8 +177,16 @@ export class StreamManager extends EventDispatcher {
|
||||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) {
|
if (this.stream.hasAudio) {
|
||||||
this.stream.enableVolumeChangeEvent(false);
|
if (type === 'publisherStartSpeaking') {
|
||||||
|
this.stream.enableHarkSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (type === 'publisherStopSpeaking') {
|
||||||
|
this.stream.enableHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (type === 'streamAudioVolumeChange') {
|
||||||
|
this.stream.enableHarkVolumeChangeEvent(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +213,16 @@ export class StreamManager extends EventDispatcher {
|
||||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) {
|
if (this.stream.hasAudio) {
|
||||||
this.stream.enableOnceVolumeChangeEvent(false);
|
if (type === 'publisherStartSpeaking') {
|
||||||
|
this.stream.enableOnceHarkSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (type === 'publisherStopSpeaking') {
|
||||||
|
this.stream.enableOnceHarkStoppedSpeakingEvent();
|
||||||
|
}
|
||||||
|
if (type === 'streamAudioVolumeChange') {
|
||||||
|
this.stream.enableOnceHarkVolumeChangeEvent(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -215,10 +234,25 @@ export class StreamManager extends EventDispatcher {
|
||||||
|
|
||||||
super.off(type, handler);
|
super.off(type, handler);
|
||||||
|
|
||||||
|
if (type === 'publisherStartSpeaking') {
|
||||||
|
// Both StreamManager and Session can have "publisherStartSpeaking" event listeners
|
||||||
|
const remainingStartSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
|
||||||
|
if (remainingStartSpeakingEventListeners === 0) {
|
||||||
|
this.stream.disableHarkSpeakingEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type === 'publisherStopSpeaking') {
|
||||||
|
// Both StreamManager and Session can have "publisherStopSpeaking" event listeners
|
||||||
|
const remainingStopSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
|
||||||
|
if (remainingStopSpeakingEventListeners === 0) {
|
||||||
|
this.stream.disableHarkStoppedSpeakingEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (type === 'streamAudioVolumeChange') {
|
if (type === 'streamAudioVolumeChange') {
|
||||||
let remainingVolumeEventListeners = this.ee.getListeners(type).length;
|
// Only StreamManager can have "streamAudioVolumeChange" event listeners
|
||||||
|
const remainingVolumeEventListeners = this.ee.getListeners(type).length;
|
||||||
if (remainingVolumeEventListeners === 0) {
|
if (remainingVolumeEventListeners === 0) {
|
||||||
this.stream.disableVolumeChangeEvent(false);
|
this.stream.disableHarkVolumeChangeEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,9 +453,10 @@ export class StreamManager extends EventDispatcher {
|
||||||
|
|
||||||
this.videos.forEach(streamManagerVideo => {
|
this.videos.forEach(streamManagerVideo => {
|
||||||
// Remove oncanplay event listener (only OpenVidu browser listener, not the user ones)
|
// Remove oncanplay event listener (only OpenVidu browser listener, not the user ones)
|
||||||
if(!!streamManagerVideo.video && !!streamManagerVideo.video.removeEventListener){
|
if (!!streamManagerVideo.video && !!streamManagerVideo.video.removeEventListener) {
|
||||||
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
||||||
} streamManagerVideo.canplayListenerAdded = false;
|
}
|
||||||
|
streamManagerVideo.canplayListenerAdded = false;
|
||||||
if (!!streamManagerVideo.targetElement) {
|
if (!!streamManagerVideo.targetElement) {
|
||||||
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
||||||
// and Session.subscribe or those created by StreamManager.createVideoElement). All this videos triggered a videoElementCreated event
|
// and Session.subscribe or those created by StreamManager.createVideoElement). All this videos triggered a videoElementCreated event
|
||||||
|
@ -486,9 +521,9 @@ export class StreamManager extends EventDispatcher {
|
||||||
this.ee.emitEvent(type, eventArray);
|
this.ee.emitEvent(type, eventArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
createVideo(): HTMLVideoElement {
|
createVideo(): HTMLVideoElement {
|
||||||
return document.createElement('video');
|
return document.createElement('video');
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,10 @@ const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packs remote media streams. Participants automatically receive them when others publish their streams. Initialized with [[Session.subscribe]] method
|
* Packs remote media streams. Participants automatically receive them when others publish their streams. Initialized with [[Session.subscribe]] method
|
||||||
|
*
|
||||||
|
* ### Available event listeners (and events dispatched)
|
||||||
|
*
|
||||||
|
* - _All events inherited from [[StreamManager]] class_
|
||||||
*/
|
*/
|
||||||
export class Subscriber extends StreamManager {
|
export class Subscriber extends StreamManager {
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,17 @@
|
||||||
|
|
||||||
import { Event } from './Event';
|
import { Event } from './Event';
|
||||||
import { Connection } from '../../OpenVidu/Connection';
|
import { Connection } from '../../OpenVidu/Connection';
|
||||||
import { Session } from '../..';
|
import { Session } from '../../OpenVidu/Session';
|
||||||
|
import { StreamManager } from '../../OpenVidu/StreamManager';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the following events:
|
* Defines the following events:
|
||||||
* - `publisherStartSpeaking`: dispatched by [[Session]] when a remote user has started speaking
|
* - `publisherStartSpeaking`: dispatched by [[Session]] and [[StreamManager]] when a user has started speaking
|
||||||
* - `publisherStopSpeaking`: dispatched by [[Session]] when a remote user has stopped speaking
|
* - `publisherStopSpeaking`: dispatched by [[Session]] and [[StreamManager]] when a user has stopped speaking
|
||||||
*
|
*
|
||||||
* More information:
|
* More information:
|
||||||
* - This events will only be triggered for **remote streams that have audio tracks** ([[Stream.hasAudio]] must be true)
|
* - This events will only be triggered for **streams that have audio tracks** ([[Stream.hasAudio]] must be true)
|
||||||
* - You can further configure how the events are dispatched by setting property `publisherSpeakingEventsOptions` in the call of [[OpenVidu.setAdvancedConfiguration]]
|
* - You can further configure how the events are dispatched by setting property `publisherSpeakingEventsOptions` in the call of [[OpenVidu.setAdvancedConfiguration]]
|
||||||
*/
|
*/
|
||||||
export class PublisherSpeakingEvent extends Event {
|
export class PublisherSpeakingEvent extends Event {
|
||||||
|
@ -44,7 +45,7 @@ export class PublisherSpeakingEvent extends Event {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
constructor(target: Session, type: string, connection: Connection, streamId: string) {
|
constructor(target: Session | StreamManager, type: string, connection: Connection, streamId: string) {
|
||||||
super(false, target, type);
|
super(false, target, type);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
Loading…
Reference in New Issue