react-native-webrtc2
Version:
WebRTC for React Native
148 lines (127 loc) • 4.68 kB
JavaScript
;
import {NativeModules} from 'react-native';
import EventTarget from 'event-target-shim';
import uuid from 'uuid';
//--添加代码
import {DeviceEventEmitter} from 'react-native';
//end
import MediaStreamTrack from './MediaStreamTrack';
//--添加代码
import MediaStreamTrackEvent from './MediaStreamTrackEvent';
//end
const {WebRTCModule} = NativeModules;
const MEDIA_STREAM_EVENTS = [
'active',
'inactive',
'addtrack',
'removetrack',
];
export default class MediaStream extends EventTarget(MEDIA_STREAM_EVENTS) {
id: string;
active: boolean = true;
onactive: ?Function;
oninactive: ?Function;
onaddtrack: ?Function;
onremovetrack: ?Function;
_tracks: Array<MediaStreamTrack> = [];
/**
* The identifier of this MediaStream unique within the associated
* WebRTCModule instance. As the id of a remote MediaStream instance is unique
* only within the associated RTCPeerConnection, it is not sufficiently unique
* to identify this MediaStream across multiple RTCPeerConnections and to
* unambiguously differentiate it from a local MediaStream instance not added
* to an RTCPeerConnection.
*/
_reactTag: string;
/**
* A MediaStream can be constructed in several ways, depending on the paramters
* that are passed here.
*
* - undefined: just a new stream, with no tracks.
* - MediaStream instance: a new stream, with a copy of the tracks of the passed stream.
* - Array of MediaStreamTrack: a new stream with a copy of the tracks in the array.
* - object: a new stream instance, represented by the passed info object, this is always
* done internally, when the stream is first created in native and the JS wrapper is
* built afterwards.
*/
constructor(arg) {
super();
// Assigm a UUID to start with. It may get overridden for remote streams.
this.id = uuid.v4();
// Local MediaStreams are created by WebRTCModule to have their id and
// reactTag equal because WebRTCModule follows the respective standard's
// recommendation for id generation i.e. uses UUID which is unique enough
// for the purposes of reactTag.
this._reactTag = this.id;
if (typeof arg === 'undefined') {
WebRTCModule.mediaStreamCreate(this.id);
} else if (arg instanceof MediaStream) {
WebRTCModule.mediaStreamCreate(this.id);
for (const track of arg.getTracks()) {
this.addTrack(track);
}
} else if (Array.isArray(arg)) {
WebRTCModule.mediaStreamCreate(this.id);
for (const track of arg) {
this.addTrack(track);
}
} else if (typeof arg === 'object' && arg.streamId && arg.streamReactTag && arg.tracks) {
this.id = arg.streamId;
this._reactTag = arg.streamReactTag;
for (const trackInfo of arg.tracks) {
// We are not using addTrack here because the track is already part of the
// stream, so there is no need to add it on the native side.
this._tracks.push(new MediaStreamTrack(trackInfo));
}
} else {
throw new TypeError(`invalid type: ${typeof arg}`);
}
//--添加代码
DeviceEventEmitter.addListener('mediaStreamTrackMuteChanged', ev => {
const track = this.getTrackById(ev.trackId);
if (track) {
track.muted = ev.muted;
const eventName = ev.muted ? 'mute' : 'unmute';
track.dispatchEvent(new MediaStreamTrackEvent(eventName, {track}));
}
})
//end
}
addTrack(track: MediaStreamTrack) {
const index = this._tracks.indexOf(track);
if (index !== -1) {
return;
}
this._tracks.push(track);
WebRTCModule.mediaStreamAddTrack(this._reactTag, track.id);
}
removeTrack(track: MediaStreamTrack) {
const index = this._tracks.indexOf(track);
if (index === -1) {
return;
}
this._tracks.splice(index, 1);
WebRTCModule.mediaStreamRemoveTrack(this._reactTag, track.id);
}
getTracks(): Array<MediaStreamTrack> {
return this._tracks.slice();
}
getTrackById(trackId): ?MediaStreamTrack {
return this._tracks.find(track => track.id === trackId);
}
getAudioTracks(): Array<MediaStreamTrack> {
return this._tracks.filter(track => track.kind === 'audio');
}
getVideoTracks(): Array<MediaStreamTrack> {
return this._tracks.filter(track => track.kind === 'video');
}
clone() {
throw new Error('Not implemented.');
}
toURL() {
return this._reactTag;
}
release() {
WebRTCModule.mediaStreamRelease(this._reactTag);
}
}