Skip to content

Commit

Permalink
feat(MeetingJsonAdapter): implement getStream
Browse files Browse the repository at this point in the history
Co-authored-by: arash koushkebaghi <[email protected]>
  • Loading branch information
taymoork2 and akoushke committed Dec 19, 2019
1 parent 7e3a5cb commit 1796006
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 15 deletions.
44 changes: 31 additions & 13 deletions src/adapters/MeetingsJSONAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {concat, from, fromEvent, Observable} from 'rxjs';
import {concat, from, fromEvent, Observable, of} from 'rxjs';
import {filter, flatMap, map} from 'rxjs/operators';
import {MeetingsAdapter, MeetingControlState} from '@webex/component-adapter-interfaces';

Expand Down Expand Up @@ -92,13 +92,27 @@ export default class MeetingsJSONAdapter extends MeetingsAdapter {
observer.complete();
});

// Attach local media stream if meeting `localVideo` property is not `null`.
// Attach media stream if any of the meeting's media stream properties are not `null`.
// We can not attach the MediaStream object in a JSON module, the work needs
// to be done here.
const getMeetingWithLocalMedia$ = getMeeting$.pipe(
const getMeetingWithMedia$ = getMeeting$.pipe(
/* eslint-disable no-confusing-arrow */
flatMap((meeting) =>
from(this.getLocalVideo()).pipe(map((localVideo) => (meeting.localVideo ? {...meeting, localVideo} : meeting)))
meeting.localVideo
? from(this.getStream({video: true, audio: false})).pipe(map((localVideo) => ({...meeting, localVideo})))
: of(meeting)
),
flatMap((meeting) =>
meeting.remoteVideo
? from(this.getStream({video: true, audio: false})).pipe(map((remoteVideo) => ({...meeting, remoteVideo})))
: of(meeting)
),
flatMap((meeting) =>
meeting.remoteAudio
? from(this.getStream({video: false, audio: true})).pipe(map((remoteAudio) => ({...meeting, remoteAudio})))
: of(meeting)
)
/* eslint-enable no-confusing-arrow */
);

// Send updates on the meeting when a mute event is triggered
Expand All @@ -107,25 +121,29 @@ export default class MeetingsJSONAdapter extends MeetingsAdapter {
map((event) => event.detail)
);

return concat(getMeetingWithLocalMedia$, muteEvent$);
return concat(getMeetingWithMedia$, muteEvent$);
}

/**
* Returns a MediaStream object obtained from local user media.
* Returns a MediaStream object obtained from user local media.
* @param {MediaStreamConstraints} constraints an object specifying the types of the media to request
* @returns {MediaStream}
*/
async getLocalVideo() {
const constraints = {
video: true,
audio: false,
};
async getStream(constraints) {
let stream;

try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints);

// filter out either video or audio from a given constraints and return a new media stream
if (constraints.video) {
stream = new MediaStream([mediaStream.getVideoTracks()[0]]);
} else {
stream = new MediaStream([mediaStream.getAudioTracks()[0]]);
}
} catch (reason) {
// eslint-disable-next-line no-console
console.error('Meetings JSON adapter can not display the user local stream', reason);
console.error('Meetings JSON adapter can not display the local user stream', reason);
}

return stream;
Expand Down
17 changes: 15 additions & 2 deletions src/adapters/MeetingsJSONAdapter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ describe('Meetings JSON Adapter', () => {
beforeEach(() => {
[meetingID] = Object.keys(meetings);
meetingsJSONAdapter = new MeetingsJSONAdapter(meetings);
meetingsJSONAdapter.getLocalVideo = jest.fn(() => Promise.resolve('mock-stream'));
});

afterEach(() => {
Expand All @@ -31,7 +30,21 @@ describe('Meetings JSON Adapter', () => {

test('renders the local media if localVideo property is defined', (done) => {
meetingsJSONAdapter.getMeeting('localVideo').subscribe((data) => {
expect(data.localVideo).toEqual('mock-stream');
expect(data.localVideo).toEqual({control: 'video'});
done();
});
});

test('renders the remote video if remoteVideo property is defined', (done) => {
meetingsJSONAdapter.getMeeting('remoteVideo').subscribe((data) => {
expect(data.remoteVideo).toEqual({control: 'video'});
done();
});
});

test('renders the remote audio if remoteAudio property is defined', (done) => {
meetingsJSONAdapter.getMeeting('remoteAudio').subscribe((data) => {
expect(data.remoteAudio).toEqual({control: 'audio'});
done();
});
});
Expand Down

0 comments on commit 1796006

Please sign in to comment.