Skip to content

Commit

Permalink
Removed mediaStream from stream class
Browse files Browse the repository at this point in the history
  • Loading branch information
CSantosM committed Jan 9, 2024
1 parent 4d122af commit 87ff212
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 188 deletions.
2 changes: 0 additions & 2 deletions openvidu-browser/src/OpenVidu/Connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,8 @@ export class Connection {
* @hidden
*/
addStream(stream: Stream): void {

stream.connection = this;
this.stream = stream;
// throw new Error("'addStream' method is not ready yet.");
}

/**
Expand Down
109 changes: 55 additions & 54 deletions openvidu-browser/src/OpenVidu/Publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
AudioCaptureOptions,
LocalAudioTrack,
LocalTrack,
LocalTrackPublication,
LocalVideoTrack,
Room,
ScreenShareCaptureOptions,
Expand Down Expand Up @@ -120,7 +121,16 @@ export class Publisher extends StreamManager {
* @hidden
*/
get videoReference(): HTMLVideoElement {
return this.stream.videoTrack?.attachedElements[0] as HTMLVideoElement;
let element!: HTMLVideoElement;
this.stream.session.room.localParticipant.videoTracks.forEach((track) => {
element = track.track?.attachedElements[0] as HTMLVideoElement;
});

if (!element) {

return this.stream.temporalVideoTrack?.attachedElements[0] as HTMLVideoElement;
}
return element;
}

/**
Expand Down Expand Up @@ -225,7 +235,7 @@ export class Publisher extends StreamManager {
await this.session.room.localParticipant.setCameraEnabled(enabled);
this.stream.videoActive = enabled;
return;
throw new Error("'publishVideo' method is not ready yet");

return new Promise(async (resolve, reject) => {
if (this.stream.videoActive !== enabled) {
const affectedMediaStream: MediaStream = this.stream.displayMyRemote()
Expand All @@ -243,10 +253,10 @@ export class Publisher extends StreamManager {
});

// There is a Virtual Background filter applied that must be removed in case the hardware must be freed
if (!enabled && resource === true && !!this.stream.filter && this.stream.filter.type.startsWith('VB:')) {
this.stream.lastVBFilter = this.stream.filter; // Save the filter to be re-applied in case of unmute
await this.stream.removeFilterAux(true);
}
// if (!enabled && resource === true && !!this.stream.filter && this.stream.filter.type.startsWith('VB:')) {
// this.stream.lastVBFilter = this.stream.filter; // Save the filter to be re-applied in case of unmute
// await this.stream.removeFilterAux(true);
// }

if (mustRestartMediaStream) {
const oldVideoTrack = affectedMediaStream.getVideoTracks()[0];
Expand Down Expand Up @@ -286,34 +296,12 @@ export class Publisher extends StreamManager {
}

if (!!this.session && !!this.stream.streamId) {
this.session.openvidu.sendRequest(
'streamPropertyChanged',
{
streamId: this.stream.streamId,
property: 'videoActive',
newValue: enabled,
reason: 'publishVideo'
},
(error, response) => {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
} else {
this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent(
this.session,
this.stream,
'videoActive',
enabled,
!enabled,
'publishVideo'
)
]);
this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent(this, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
}
}
);
this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent(this.session, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent(this, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
}
this.stream.videoActive = enabled;
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its video stream');
Expand Down Expand Up @@ -419,15 +407,15 @@ export class Publisher extends StreamManager {
* @returns A Promise (to which you can optionally subscribe to) that is resolved if the track was successfully replaced and rejected with an Error object in other case
*/
async replaceTrack(track: MediaStreamTrack): Promise<void> {

const localTracks = this.session.room.localParticipant.getTracks();
const trackKind = track.kind;

if(localTracks.some((t) => t.isMuted)){
debugger;
console.log(this.videoReference);
if (localTracks.some((t) => t.isMuted)) {
console.error('Cannot replace track while muted');
return;
}
console.log(track.getSettings());
const kind: MediaDeviceKind = track.kind === 'audio' ? 'audioinput' : 'videoinput';
const deviceId = track.getSettings().deviceId;
if (!!kind && !!deviceId) {
Expand All @@ -436,7 +424,7 @@ export class Publisher extends StreamManager {
if (trackMatched) {
const videoTrack: LocalVideoTrack = trackMatched.track as LocalVideoTrack;
videoTrack.attach(this.videoReference);
this.stream.videoTrack = videoTrack;
this.stream.temporalVideoTrack = videoTrack;
} else {
console.error(`The participant does not have a ${trackKind} track`);
}
Expand Down Expand Up @@ -511,10 +499,9 @@ export class Publisher extends StreamManager {
constraintsAux.video = constraints.video;
startTime = Date.now();


// this.setPermissionDialogTimer(timeForDialogEvent);
try {
if (this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron()) {
if (this.stream.isSendScreen() /*&& navigator.mediaDevices['getDisplayMedia']*/ && !platform.isElectron()) {
// throw new Error('SCREEN getDisplayMedia not implemented yet');

const screenTrackOptions: ScreenShareCaptureOptions = {
Expand All @@ -523,21 +510,32 @@ export class Publisher extends StreamManager {
systemAudio: 'include'
};


// const mediaStream = await navigator.mediaDevices['getDisplayMedia']({ video: true, audio: this.properties.audioSource === 'screen' });
const myScreenTracks = await createLocalScreenTracks(screenTrackOptions);
this.accessAllowed = true;
this.accessDenied = false;
const screenVideoTrack = myScreenTracks.find((t) => t.kind === 'video') as LocalVideoTrack;
screenVideoTrack.mediaStreamTrack.contentHint = 'detail';
console.log('screenVideoTrack', screenVideoTrack);

console.log('screenVideoTrack', screenVideoTrack.mediaStreamTrack.contentHint);
const screenAdudioTrack = myScreenTracks.find((t) => t.kind === 'audio') as LocalAudioTrack;

// Generate a MediaStream with the screen track and the audio track
// const mediaStream = new MediaStream();
// myScreenTracks.forEach((track: LocalTrack) => {
// mediaStream.addTrack(track.mediaStreamTrack);
// });
if (screenVideoTrack) {
// mediaStream.addTrack(screenVideoTrack.mediaStreamTrack);
this.stream.temporalVideoScreenTrack = screenVideoTrack;
this.stream.temporalVideoTrack = undefined;
}
if (screenAdudioTrack) {
// mediaStream.addTrack(screenVideoTrack.mediaStreamTrack);
this.stream.temporalAudioScreenTrack = screenAdudioTrack;
this.stream.temporalAudioTrack = undefined;
}
// this.stream.setMediaStream(mediaStream);

// this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream);
// await getMediaSuccess(mediaStream, definedAudioConstraint);
this.accessAllowed = true;
this.accessDenied = false;
this.stream.videoScreenTrack = myScreenTracks.find((t) => t.kind === 'video') as LocalVideoTrack;
this.stream.audioScreenTrack = myScreenTracks.find((t) => t.kind === 'audio') as LocalAudioTrack;

this.stream.isLocalStreamReadyToPublish = true;
this.stream.ee.emitEvent('stream-ready-to-publish', []);
Expand All @@ -554,15 +552,18 @@ export class Publisher extends StreamManager {

this.accessAllowed = true;
this.accessDenied = false;
this.stream.videoTrack = myVideoTrack;
this.stream.audioTrack = myAudioTrack;
this.stream.temporalVideoTrack = myVideoTrack;
this.stream.temporalAudioTrack = myAudioTrack;
this.stream.temporalVideoScreenTrack = undefined;
this.stream.temporalAudioScreenTrack = undefined;

// Generate a MediaStream with the screen track and the audio track
// const mediaStream = new MediaStream();
// mediaStream.addTrack(myVideoTrack.mediaStreamTrack);
// mediaStream.addTrack(myAudioTrack.mediaStreamTrack);

// console.log('setting media stream', mediaStream);
// this.stream.setMediaStream(mediaStream);
// console.log('setting media stream', mediaStream);

this.stream.isLocalStreamReadyToPublish = true;
this.stream.ee.emitEvent('stream-ready-to-publish', []);
}
Expand Down Expand Up @@ -964,7 +965,7 @@ export class Publisher extends StreamManager {
* @hidden
*/
reestablishStreamPlayingEvent() {
throw new Error("'reestablishStreamPlayingEvent' method is not ready yet");
// throw new Error("'reestablishStreamPlayingEvent' method is not ready yet");
if (this.ee.getListeners('streamPlaying').length > 0) {
this.addPlayEventToFirstVideo();
}
Expand Down
87 changes: 50 additions & 37 deletions openvidu-browser/src/OpenVidu/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { ExceptionEvent, ExceptionEventName } from '../OpenViduInternal/Events/E
import {
ConnectionQuality,
ConnectionState,
LocalTrack,
LocalTrackPublication,
Participant,
RemoteAudioTrack,
Expand Down Expand Up @@ -545,49 +546,56 @@ export class Session extends EventDispatcher {
*
* See {@link StreamEvent} and {@link VideoElementEvent} to learn more.
*/
unpublish(publisher: Publisher): Promise<void> {
throw new Error("'unpublish' method is not ready yet.");
return new Promise((resolve, reject) => {
if (!this.sessionConnected()) {
throw this.notConnectedError();
}
async unpublish(publisher: Publisher): Promise<void> {
// throw new Error("'unpublish' method is not ready yet.");
// return new Promise((resolve, reject) => {
if (!this.sessionConnected()) {
throw this.notConnectedError();
}

const stream = publisher.stream;
const stream = publisher.stream;

if (!stream.connection) {
return reject(new Error('The associated Connection object of this Publisher is null'));
} else if (stream.connection !== this.connection) {
return reject(
new Error(
'The associated Connection object of this Publisher is not your local Connection. ' +
"Only moderators can force unpublish on remote Streams via 'forceUnpublish' method"
)
);
} else {
logger.info('Unpublishing local media (' + stream.connection.connectionId + ')');
if (!stream.connection) {
throw new Error('The associated Connection object of this Publisher is null');
} else if (stream.connection !== this.connection) {
throw new Error(
'The associated Connection object of this Publisher is not your local Connection. ' +
"Only moderators can force unpublish on remote Streams via 'forceUnpublish' method"
);
} else {
logger.info('Unpublishing local media (' + stream.connection.connectionId + ')');

this.openvidu.sendRequest('unpublishVideo', (error, response) => {
if (error) {
return reject(error);
} else {
logger.info('Media unpublished correctly');
// this.openvidu.sendRequest('unpublishVideo', (error, response) => {
// if (error) {
// return reject(error);
// } else {

stream.disposeWebRtcPeer();
let tracks: LocalTrack[] = [];
this.room.localParticipant.tracks.forEach((track) => {
if(track.track) {
tracks.push(track.track);
}
});

if (stream.connection.stream == stream) {
// The Connection.stream may have changed if Session.publish was called with other Publisher
delete stream.connection.stream;
}
await this.room.localParticipant.unpublishTracks(tracks);
logger.info('Media unpublished correctly');

const streamEvent = new StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish');
publisher.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
// stream.disposeWebRtcPeer();

return resolve();
}
});
if (stream.connection.stream == stream) {
// The Connection.stream may have changed if Session.publish was called with other Publisher
delete stream.connection.stream;
}
});

const streamEvent = new StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish');
publisher.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();

// return resolve();
// }
// });
}
// });
}

/**
Expand Down Expand Up @@ -895,8 +903,13 @@ export class Session extends EventDispatcher {
console.warn('exception event not implemented in SessionAdapter');
break;
// case 'publisherStartSpeaking':
// this.room.on(RoomEvent.ActiveSpeakersChanged, (speakers: Participant[]) => {

// console.log('speakers', speakers);
// });
// break;
// case 'publisherStopSpeaking':

// break;
// case 'broadcastStarted':
// break;
Expand Down Expand Up @@ -1211,11 +1224,11 @@ export class Session extends EventDispatcher {
// connection.stream?.setMediaStream(mediaStream);
if (connection.stream) {
if (videoPublication?.videoTrack) {
connection.stream.videoTrack = videoPublication.videoTrack as RemoteVideoTrack;
connection.stream.temporalVideoTrack = videoPublication.videoTrack as RemoteVideoTrack;
}

if (audioPublication?.audioTrack) {
connection.stream.audioTrack = audioPublication.audioTrack as RemoteAudioTrack;
connection.stream.temporalAudioTrack = audioPublication.audioTrack as RemoteAudioTrack;
}
}

Expand Down
Loading

0 comments on commit 87ff212

Please sign in to comment.