@sbhjt-gr/react-native-webrtc 137.0.2 → 137.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java +101 -1
- package/ios/RCTWebRTC/WebRTCModule+RTCMediaStream.m +136 -1
- package/ios/RCTWebRTC/WebRTCModule.h +2 -0
- package/ios/RCTWebRTC/WebRTCModule.m +3 -0
- package/lib/commonjs/EventEmitter.js +3 -1
- package/lib/commonjs/EventEmitter.js.map +1 -1
- package/lib/commonjs/MediaStreamTrack.js.map +1 -1
- package/lib/module/EventEmitter.js +3 -1
- package/lib/module/EventEmitter.js.map +1 -1
- package/lib/module/MediaStreamTrack.js.map +1 -1
- package/lib/typescript/MediaStreamTrack.d.ts +2 -0
- package/package.json +1 -1
- package/src/EventEmitter.ts +7 -3
- package/src/MediaStreamTrack.ts +6 -3
|
@@ -27,6 +27,7 @@ import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
|
|
|
27
27
|
import org.webrtc.AddIceObserver;
|
|
28
28
|
import org.webrtc.AudioProcessingFactory;
|
|
29
29
|
import org.webrtc.AudioTrack;
|
|
30
|
+
import org.webrtc.AudioTrackSink;
|
|
30
31
|
import org.webrtc.CryptoOptions;
|
|
31
32
|
import org.webrtc.EglBase;
|
|
32
33
|
import org.webrtc.IceCandidate;
|
|
@@ -52,12 +53,17 @@ import org.webrtc.VideoTrack;
|
|
|
52
53
|
import org.webrtc.audio.AudioDeviceModule;
|
|
53
54
|
import org.webrtc.audio.JavaAudioDeviceModule;
|
|
54
55
|
|
|
56
|
+
import java.nio.ByteBuffer;
|
|
57
|
+
import java.nio.ByteOrder;
|
|
58
|
+
import java.nio.IntBuffer;
|
|
59
|
+
import java.nio.ShortBuffer;
|
|
55
60
|
import java.util.ArrayList;
|
|
56
61
|
import java.util.HashMap;
|
|
57
62
|
import java.util.List;
|
|
58
63
|
import java.util.Map;
|
|
59
64
|
import java.util.Objects;
|
|
60
65
|
import java.util.concurrent.Callable;
|
|
66
|
+
import java.util.concurrent.ConcurrentHashMap;
|
|
61
67
|
import java.util.concurrent.ExecutionException;
|
|
62
68
|
|
|
63
69
|
@ReactModule(name = "WebRTCModule")
|
|
@@ -72,6 +78,7 @@ public class WebRTCModule extends ReactContextBaseJavaModule {
|
|
|
72
78
|
// Need to expose the peer connection codec factories here to get capabilities
|
|
73
79
|
private final SparseArray<PeerConnectionObserver> mPeerConnectionObservers;
|
|
74
80
|
final Map<String, MediaStream> localStreams;
|
|
81
|
+
private final Map<String, AudioTrackSink> audioSinkMap = new ConcurrentHashMap<>();
|
|
75
82
|
|
|
76
83
|
private final GetUserMediaImpl getUserMediaImpl;
|
|
77
84
|
|
|
@@ -479,6 +486,10 @@ public class WebRTCModule extends ReactContextBaseJavaModule {
|
|
|
479
486
|
return pco.remoteTracks.get(trackId);
|
|
480
487
|
}
|
|
481
488
|
|
|
489
|
+
private String audioSinkKey(int pcId, String trackId) {
|
|
490
|
+
return pcId + ":" + trackId;
|
|
491
|
+
}
|
|
492
|
+
|
|
482
493
|
MediaStreamTrack getLocalTrack(String trackId) {
|
|
483
494
|
return getUserMediaImpl.getTrack(trackId);
|
|
484
495
|
}
|
|
@@ -971,9 +982,98 @@ public class WebRTCModule extends ReactContextBaseJavaModule {
|
|
|
971
982
|
});
|
|
972
983
|
}
|
|
973
984
|
|
|
985
|
+
private class AudioSamplesInterceptor implements AudioTrackSink {
|
|
986
|
+
private final String trackId;
|
|
987
|
+
|
|
988
|
+
AudioSamplesInterceptor(String trackId) {
|
|
989
|
+
this.trackId = trackId;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
@Override
|
|
993
|
+
public void onData(
|
|
994
|
+
ByteBuffer audioData,
|
|
995
|
+
int bitsPerSample,
|
|
996
|
+
int sampleRate,
|
|
997
|
+
int numberOfChannels,
|
|
998
|
+
int numberOfFrames,
|
|
999
|
+
long absoluteCaptureTimestampMs) {
|
|
1000
|
+
WritableMap params = Arguments.createMap();
|
|
1001
|
+
params.putString("trackId", trackId);
|
|
1002
|
+
params.putArray("samples", convertSamples(audioData, bitsPerSample));
|
|
1003
|
+
params.putInt("sampleRate", sampleRate);
|
|
1004
|
+
params.putInt("channels", numberOfChannels);
|
|
1005
|
+
params.putInt("bitsPerSample", bitsPerSample);
|
|
1006
|
+
params.putInt("framesPerBuffer", numberOfFrames);
|
|
1007
|
+
params.putDouble("timestamp", (double) absoluteCaptureTimestampMs);
|
|
1008
|
+
|
|
1009
|
+
sendEvent("audioSamples", params);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
private WritableArray convertSamples(ByteBuffer audioData, int bitsPerSample) {
|
|
1013
|
+
WritableArray samples = Arguments.createArray();
|
|
1014
|
+
if (audioData == null) {
|
|
1015
|
+
return samples;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
ByteBuffer buffer = audioData.slice().order(ByteOrder.LITTLE_ENDIAN);
|
|
1019
|
+
|
|
1020
|
+
if (bitsPerSample == 16) {
|
|
1021
|
+
ShortBuffer shortBuffer = buffer.asShortBuffer();
|
|
1022
|
+
while (shortBuffer.hasRemaining()) {
|
|
1023
|
+
samples.pushDouble(shortBuffer.get());
|
|
1024
|
+
}
|
|
1025
|
+
} else if (bitsPerSample == 32) {
|
|
1026
|
+
IntBuffer intBuffer = buffer.asIntBuffer();
|
|
1027
|
+
while (intBuffer.hasRemaining()) {
|
|
1028
|
+
samples.pushDouble(intBuffer.get());
|
|
1029
|
+
}
|
|
1030
|
+
} else {
|
|
1031
|
+
while (buffer.hasRemaining()) {
|
|
1032
|
+
samples.pushDouble(buffer.get());
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
return samples;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
974
1040
|
@ReactMethod
|
|
975
1041
|
public void mediaStreamTrackEnableAudioSink(int pcId, String id, boolean enabled) {
|
|
976
|
-
|
|
1042
|
+
ThreadUtils.runOnExecutor(() -> {
|
|
1043
|
+
String sinkKey = audioSinkKey(pcId, id);
|
|
1044
|
+
|
|
1045
|
+
if (enabled) {
|
|
1046
|
+
if (audioSinkMap.containsKey(sinkKey)) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
MediaStreamTrack track = getTrack(pcId, id);
|
|
1051
|
+
if (track == null) {
|
|
1052
|
+
Log.d(TAG, "mediaStreamTrackEnableAudioSink() could not find track " + id);
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (!(track instanceof AudioTrack)) {
|
|
1057
|
+
Log.d(TAG, "mediaStreamTrackEnableAudioSink() track is not an AudioTrack!");
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
AudioSamplesInterceptor sink = new AudioSamplesInterceptor(id);
|
|
1062
|
+
((AudioTrack) track).addSink(sink);
|
|
1063
|
+
audioSinkMap.put(sinkKey, sink);
|
|
1064
|
+
} else {
|
|
1065
|
+
AudioTrackSink sink = audioSinkMap.remove(sinkKey);
|
|
1066
|
+
|
|
1067
|
+
if (sink == null) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
MediaStreamTrack track = getTrack(pcId, id);
|
|
1072
|
+
if (track instanceof AudioTrack) {
|
|
1073
|
+
((AudioTrack) track).removeSink(sink);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
977
1077
|
}
|
|
978
1078
|
|
|
979
1079
|
/**
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#import <objc/runtime.h>
|
|
2
2
|
|
|
3
|
+
#import <AVFoundation/AVFoundation.h>
|
|
4
|
+
#import <math.h>
|
|
5
|
+
#import <limits.h>
|
|
6
|
+
#import <stdint.h>
|
|
7
|
+
|
|
3
8
|
#import <WebRTC/RTCCameraVideoCapturer.h>
|
|
4
9
|
#import <WebRTC/RTCMediaConstraints.h>
|
|
5
10
|
#import <WebRTC/RTCMediaStreamTrack.h>
|
|
@@ -16,8 +21,109 @@
|
|
|
16
21
|
#import "TrackCapturerEventsEmitter.h"
|
|
17
22
|
#import "VideoCaptureController.h"
|
|
18
23
|
|
|
24
|
+
@interface AudioSamplesRenderer : NSObject<RTCAudioRenderer>
|
|
25
|
+
|
|
26
|
+
- (instancetype)initWithModule:(WebRTCModule *)module trackId:(NSString *)trackId;
|
|
27
|
+
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
@implementation AudioSamplesRenderer {
|
|
31
|
+
__weak WebRTCModule *_module;
|
|
32
|
+
NSString *_trackId;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (instancetype)initWithModule:(WebRTCModule *)module trackId:(NSString *)trackId {
|
|
36
|
+
self = [super init];
|
|
37
|
+
if (self) {
|
|
38
|
+
_module = module;
|
|
39
|
+
_trackId = [trackId copy];
|
|
40
|
+
}
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (void)render:(AVAudioPCMBuffer *)pcmBuffer {
|
|
45
|
+
WebRTCModule *module = _module;
|
|
46
|
+
if (!module) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
AVAudioFrameCount frameLength = pcmBuffer.frameLength;
|
|
51
|
+
if (frameLength == 0) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
UInt32 channelCount = pcmBuffer.format.channelCount;
|
|
56
|
+
if (channelCount == 0) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
AVAudioCommonFormat format = pcmBuffer.format.commonFormat;
|
|
61
|
+
NSUInteger totalSamples = (NSUInteger)frameLength * (NSUInteger)channelCount;
|
|
62
|
+
NSMutableArray<NSNumber *> *samples = [NSMutableArray arrayWithCapacity:totalSamples];
|
|
63
|
+
int bitsPerSample = (int)pcmBuffer.format.streamDescription->mBitsPerChannel;
|
|
64
|
+
|
|
65
|
+
if (format == AVAudioPCMFormatInt16) {
|
|
66
|
+
int16_t **channelData = pcmBuffer.int16ChannelData;
|
|
67
|
+
if (!channelData) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
for (AVAudioFrameCount frame = 0; frame < frameLength; frame++) {
|
|
71
|
+
for (UInt32 channel = 0; channel < channelCount; channel++) {
|
|
72
|
+
[samples addObject:@(channelData[channel][frame])];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} else if (format == AVAudioPCMFormatFloat32) {
|
|
76
|
+
float **channelData = pcmBuffer.floatChannelData;
|
|
77
|
+
if (!channelData) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
bitsPerSample = 16;
|
|
81
|
+
for (AVAudioFrameCount frame = 0; frame < frameLength; frame++) {
|
|
82
|
+
for (UInt32 channel = 0; channel < channelCount; channel++) {
|
|
83
|
+
float value = channelData[channel][frame];
|
|
84
|
+
float clipped = fminf(fmaxf(value, -1.0f), 1.0f);
|
|
85
|
+
int16_t sample = (int16_t)lrintf(clipped * (float)INT16_MAX);
|
|
86
|
+
[samples addObject:@(sample)];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} else if (format == AVAudioPCMFormatInt32) {
|
|
90
|
+
int32_t **channelData = pcmBuffer.int32ChannelData;
|
|
91
|
+
if (!channelData) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
bitsPerSample = 32;
|
|
95
|
+
for (AVAudioFrameCount frame = 0; frame < frameLength; frame++) {
|
|
96
|
+
for (UInt32 channel = 0; channel < channelCount; channel++) {
|
|
97
|
+
int32_t value = channelData[channel][frame];
|
|
98
|
+
[samples addObject:@(value)];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
NSTimeInterval timestampMs = [[NSDate date] timeIntervalSince1970] * 1000.0;
|
|
106
|
+
|
|
107
|
+
[module sendEventWithName:kEventAudioSamples
|
|
108
|
+
body:@{
|
|
109
|
+
@"trackId" : _trackId,
|
|
110
|
+
@"samples" : samples,
|
|
111
|
+
@"sampleRate" : @(pcmBuffer.format.sampleRate),
|
|
112
|
+
@"channels" : @(channelCount),
|
|
113
|
+
@"bitsPerSample" : @(bitsPerSample),
|
|
114
|
+
@"framesPerBuffer" : @(frameLength),
|
|
115
|
+
@"timestamp" : @(timestampMs)
|
|
116
|
+
}];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@end
|
|
120
|
+
|
|
19
121
|
@implementation WebRTCModule (RTCMediaStream)
|
|
20
122
|
|
|
123
|
+
- (NSString *)audioSinkKeyForPcId:(NSNumber *)pcId trackId:(NSString *)trackId {
|
|
124
|
+
return [NSString stringWithFormat:@"%@:%@", pcId, trackId];
|
|
125
|
+
}
|
|
126
|
+
|
|
21
127
|
- (VideoEffectProcessor *)videoEffectProcessor {
|
|
22
128
|
return objc_getAssociatedObject(self, _cmd);
|
|
23
129
|
}
|
|
@@ -497,7 +603,36 @@ RCT_EXPORT_METHOD(mediaStreamTrackSetPlaybackEnabled : (nonnull NSNumber *)pcId
|
|
|
497
603
|
}
|
|
498
604
|
|
|
499
605
|
RCT_EXPORT_METHOD(mediaStreamTrackEnableAudioSink : (nonnull NSNumber *)pcId : (nonnull NSString *)trackID : (BOOL)enabled) {
|
|
500
|
-
|
|
606
|
+
NSString *key = [self audioSinkKeyForPcId:pcId trackId:trackID];
|
|
607
|
+
|
|
608
|
+
if (enabled) {
|
|
609
|
+
if (self.audioRenderers[key]) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
RTCMediaStreamTrack *track = [self trackForId:trackID pcId:pcId];
|
|
614
|
+
if (track == nil || ![track.kind isEqualToString:@"audio"]) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
RTCAudioTrack *audioTrack = (RTCAudioTrack *)track;
|
|
619
|
+
AudioSamplesRenderer *renderer = [[AudioSamplesRenderer alloc] initWithModule:self trackId:trackID];
|
|
620
|
+
self.audioRenderers[key] = renderer;
|
|
621
|
+
[audioTrack addRenderer:renderer];
|
|
622
|
+
} else {
|
|
623
|
+
id<RTCAudioRenderer> renderer = self.audioRenderers[key];
|
|
624
|
+
if (!renderer) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
RTCMediaStreamTrack *track = [self trackForId:trackID pcId:pcId];
|
|
629
|
+
if ([track isKindOfClass:[RTCAudioTrack class]]) {
|
|
630
|
+
RTCAudioTrack *audioTrack = (RTCAudioTrack *)track;
|
|
631
|
+
[audioTrack removeRenderer:renderer];
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
[self.audioRenderers removeObjectForKey:key];
|
|
635
|
+
}
|
|
501
636
|
}
|
|
502
637
|
|
|
503
638
|
RCT_EXPORT_METHOD(mediaStreamTrackSetVideoEffects
|
|
@@ -36,6 +36,8 @@ static NSString *const kEventAudioSamples = @"audioSamples";
|
|
|
36
36
|
@property(nonatomic, strong) NSMutableDictionary<NSString *, RTCMediaStream *> *localStreams;
|
|
37
37
|
@property(nonatomic, strong) NSMutableDictionary<NSString *, RTCMediaStreamTrack *> *localTracks;
|
|
38
38
|
|
|
39
|
+
@property(nonatomic, strong) NSMutableDictionary<NSString *, id<RTCAudioRenderer>> *audioRenderers;
|
|
40
|
+
|
|
39
41
|
@property(nonatomic, strong) NSMutableDictionary<NSString *, RTCFrameCryptor *> *frameCryptors;
|
|
40
42
|
@property(nonatomic, strong) NSMutableDictionary<NSString *, RTCFrameCryptorKeyProvider *> *keyProviders;
|
|
41
43
|
@property(nonatomic, strong) NSMutableDictionary<NSString *, RTCDataPacketCryptor *> *dataPacketCryptors;
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
- (void)dealloc {
|
|
24
24
|
[_localTracks removeAllObjects];
|
|
25
25
|
_localTracks = nil;
|
|
26
|
+
[_audioRenderers removeAllObjects];
|
|
27
|
+
_audioRenderers = nil;
|
|
26
28
|
[_localStreams removeAllObjects];
|
|
27
29
|
_localStreams = nil;
|
|
28
30
|
|
|
@@ -92,6 +94,7 @@
|
|
|
92
94
|
_peerConnections = [NSMutableDictionary new];
|
|
93
95
|
_localStreams = [NSMutableDictionary new];
|
|
94
96
|
_localTracks = [NSMutableDictionary new];
|
|
97
|
+
_audioRenderers = [NSMutableDictionary new];
|
|
95
98
|
|
|
96
99
|
_frameCryptors = [NSMutableDictionary new];
|
|
97
100
|
_keyProviders = [NSMutableDictionary new];
|
|
@@ -51,7 +51,9 @@ function removeListener(listener) {
|
|
|
51
51
|
}
|
|
52
52
|
function removeListenerForEvent(listener, eventName) {
|
|
53
53
|
const subs = _subscriptions.get(listener);
|
|
54
|
-
if (!subs)
|
|
54
|
+
if (!subs) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
55
57
|
const remaining = [];
|
|
56
58
|
subs.forEach(sub => {
|
|
57
59
|
if (sub.eventType === eventName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_EventEmitter","_interopRequireDefault","obj","__esModule","default","WebRTCModule","NativeModules","nativeEmitter","NativeEventEmitter","NATIVE_EVENTS","eventEmitter","EventEmitter","setupNativeEvents","eventName","addListener","_len","arguments","length","args","Array","_key","emit","_subscriptions","Map","listener","eventHandler","_subscriptions$get","includes","Error","has","set","get","push","removeListener","_subscriptions$get2","forEach","sub","remove","delete","removeListenerForEvent","subs","remaining","eventType"],"sources":["EventEmitter.ts"],"sourcesContent":["import { NativeModules, NativeEventEmitter, EmitterSubscription } from 'react-native';\n// @ts-ignore\nimport EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';\n\nconst { WebRTCModule } = NativeModules;\n\n// This emitter is going to be used to listen to all the native events (once) and then\n// re-emit them on a JS-only emitter.\nconst nativeEmitter = new NativeEventEmitter(WebRTCModule);\n\nconst NATIVE_EVENTS = [\n 'peerConnectionSignalingStateChanged',\n 'peerConnectionStateChanged',\n 'peerConnectionOnRenegotiationNeeded',\n 'peerConnectionIceConnectionChanged',\n 'peerConnectionIceGatheringChanged',\n 'peerConnectionGotICECandidate',\n 'peerConnectionDidOpenDataChannel',\n 'peerConnectionOnRemoveTrack',\n 'peerConnectionOnTrack',\n 'dataChannelStateChanged',\n 'dataChannelReceiveMessage',\n 'dataChannelDidChangeBufferedAmount',\n 'mediaStreamTrackMuteChanged',\n 'mediaStreamTrackEnded',\n 'frameCryptionStateChanged',\n 'audioSamples',\n];\n\nconst eventEmitter = new EventEmitter();\n\nexport function setupNativeEvents() {\n for (const eventName of NATIVE_EVENTS) {\n nativeEmitter.addListener(eventName, (...args) => {\n eventEmitter.emit(eventName, ...args);\n });\n }\n}\n\ntype EventHandler = (event: unknown) => void;\ntype Listener = unknown;\n\nconst _subscriptions: Map<Listener, EmitterSubscription[]> = new Map();\n\nexport function addListener(listener: Listener, eventName: string, eventHandler: EventHandler): void {\n if (!NATIVE_EVENTS.includes(eventName)) {\n throw new Error(`Invalid event: ${eventName}`);\n }\n\n if (!_subscriptions.has(listener)) {\n _subscriptions.set(listener, []);\n }\n\n _subscriptions.get(listener)?.push(eventEmitter.addListener(eventName, eventHandler));\n}\n\nexport function removeListener(listener: Listener): void {\n _subscriptions.get(listener)?.forEach(sub => {\n sub.remove();\n });\n\n _subscriptions.delete(listener);\n}\n\nexport function removeListenerForEvent(listener: Listener, eventName: string): void {\n const subs = _subscriptions.get(listener);\n if (!subs) return;\n \n const remaining: EmitterSubscription[] = [];\n subs.forEach(sub => {\n if ((sub as any).eventType === eventName) {\n sub.remove();\n } else {\n remaining.push(sub);\n }\n });\n
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_EventEmitter","_interopRequireDefault","obj","__esModule","default","WebRTCModule","NativeModules","nativeEmitter","NativeEventEmitter","NATIVE_EVENTS","eventEmitter","EventEmitter","setupNativeEvents","eventName","addListener","_len","arguments","length","args","Array","_key","emit","_subscriptions","Map","listener","eventHandler","_subscriptions$get","includes","Error","has","set","get","push","removeListener","_subscriptions$get2","forEach","sub","remove","delete","removeListenerForEvent","subs","remaining","eventType"],"sources":["EventEmitter.ts"],"sourcesContent":["import { NativeModules, NativeEventEmitter, EmitterSubscription } from 'react-native';\n// @ts-ignore\nimport EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';\n\nconst { WebRTCModule } = NativeModules;\n\n// This emitter is going to be used to listen to all the native events (once) and then\n// re-emit them on a JS-only emitter.\nconst nativeEmitter = new NativeEventEmitter(WebRTCModule);\n\nconst NATIVE_EVENTS = [\n 'peerConnectionSignalingStateChanged',\n 'peerConnectionStateChanged',\n 'peerConnectionOnRenegotiationNeeded',\n 'peerConnectionIceConnectionChanged',\n 'peerConnectionIceGatheringChanged',\n 'peerConnectionGotICECandidate',\n 'peerConnectionDidOpenDataChannel',\n 'peerConnectionOnRemoveTrack',\n 'peerConnectionOnTrack',\n 'dataChannelStateChanged',\n 'dataChannelReceiveMessage',\n 'dataChannelDidChangeBufferedAmount',\n 'mediaStreamTrackMuteChanged',\n 'mediaStreamTrackEnded',\n 'frameCryptionStateChanged',\n 'audioSamples',\n];\n\nconst eventEmitter = new EventEmitter();\n\nexport function setupNativeEvents() {\n for (const eventName of NATIVE_EVENTS) {\n nativeEmitter.addListener(eventName, (...args) => {\n eventEmitter.emit(eventName, ...args);\n });\n }\n}\n\ntype EventHandler = (event: unknown) => void;\ntype Listener = unknown;\n\nconst _subscriptions: Map<Listener, EmitterSubscription[]> = new Map();\n\nexport function addListener(listener: Listener, eventName: string, eventHandler: EventHandler): void {\n if (!NATIVE_EVENTS.includes(eventName)) {\n throw new Error(`Invalid event: ${eventName}`);\n }\n\n if (!_subscriptions.has(listener)) {\n _subscriptions.set(listener, []);\n }\n\n _subscriptions.get(listener)?.push(eventEmitter.addListener(eventName, eventHandler));\n}\n\nexport function removeListener(listener: Listener): void {\n _subscriptions.get(listener)?.forEach(sub => {\n sub.remove();\n });\n\n _subscriptions.delete(listener);\n}\n\nexport function removeListenerForEvent(listener: Listener, eventName: string): void {\n const subs = _subscriptions.get(listener);\n\n if (!subs) {\n return;\n }\n\n const remaining: EmitterSubscription[] = [];\n\n subs.forEach(sub => {\n if ((sub as any).eventType === eventName) {\n sub.remove();\n } else {\n remaining.push(sub);\n }\n });\n\n if (remaining.length === 0) {\n _subscriptions.delete(listener);\n } else {\n _subscriptions.set(listener, remaining);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_index","require","_reactNative","_EventEmitter","_Logger","_interopRequireDefault","_RTCUtil","obj","__esModule","default","_defineProperty","key","value","Object","defineProperty","enumerable","configurable","writable","log","Logger","WebRTCModule","NativeModules","MediaStreamTrack","EventTarget","constructor","info","_constraints","constraints","_enabled","enabled","_settings","settings","_muted","_peerConnectionId","peerConnectionId","_readyState","readyState","id","kind","remote","_registerEvents","Boolean","mediaStreamTrackSetEnabled","muted","stop","_switchCamera","Error","deepClone","deviceId","facingMode","applyConstraints","_setVideoEffects","names","mediaStreamTrackSetVideoEffects","_setVideoEffect","name","_setMutedInternal","dispatchEvent","Event","_setVolume","volume","mediaStreamTrackSetVolume","normalized","normalizeConstraints","video","mediaStreamTrackApplyConstraints","clone","getCapabilities","getConstraints","getSettings","addListener","ev","trackId","debug","_setAudioSinkCallback","callback","_audioSinkCallback","_handleAudioSamples","data","setAudioSink","_audioSinkListenerActive","mediaStreamTrackEnableAudioSink","removeListenerForEvent","setPlaybackEnabled","_playbackEnabled","mediaStreamTrackSetPlaybackEnabled","isPlaybackEnabled","release","removeListener","mediaStreamTrackRelease","exports","proto","prototype","defineEventAttribute"],"sources":["MediaStreamTrack.ts"],"sourcesContent":["import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index';\nimport { NativeModules, NativeEventEmitter, Platform } from 'react-native';\n\nimport { MediaTrackConstraints } from './Constraints';\nimport { addListener, removeListener, removeListenerForEvent } from './EventEmitter';\nimport Logger from './Logger';\nimport { deepClone, normalizeConstraints } from './RTCUtil';\n\nconst log = new Logger('pc');\nconst { WebRTCModule } = NativeModules;\n\nexport type AudioSampleData = {\n trackId: string;\n samples: number[];\n sampleRate: number;\n channels: number;\n timestamp: number;\n}\n\nexport type AudioSinkCallback = (data: AudioSampleData) => void;\n\n\ntype MediaStreamTrackState = 'live' | 'ended';\n\nexport type MediaStreamTrackInfo = {\n id: string;\n kind: string;\n remote: boolean;\n constraints: object;\n enabled: boolean;\n settings: object;\n peerConnectionId: number;\n readyState: MediaStreamTrackState;\n}\n\nexport type MediaTrackSettings = {\n width?: number;\n height?: number;\n frameRate?: number;\n facingMode?: string;\n deviceId?: string;\n groupId?: string;\n}\n\ntype MediaStreamTrackEventMap = {\n ended: Event<'ended'>;\n mute: Event<'mute'>;\n unmute: Event<'unmute'>;\n}\n\nexport default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventMap> {\n _constraints: MediaTrackConstraints;\n _enabled: boolean;\n _settings: MediaTrackSettings;\n _muted: boolean;\n _peerConnectionId: number;\n _readyState: MediaStreamTrackState;\n\n readonly id: string;\n readonly kind: string;\n readonly label: string = '';\n readonly remote: boolean;\n\n constructor(info: MediaStreamTrackInfo) {\n super();\n\n this._constraints = info.constraints || {};\n this._enabled = info.enabled;\n this._settings = info.settings || {};\n this._muted = false;\n this._peerConnectionId = info.peerConnectionId;\n this._readyState = info.readyState;\n\n this.id = info.id;\n this.kind = info.kind;\n this.remote = info.remote;\n\n if (!this.remote) {\n this._registerEvents();\n }\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(enabled: boolean) {\n if (enabled === this._enabled) {\n return;\n }\n\n this._enabled = Boolean(enabled);\n\n if (this._readyState === 'ended') {\n return;\n }\n\n WebRTCModule.mediaStreamTrackSetEnabled(this.remote ? this._peerConnectionId : -1, this.id, this._enabled);\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n get readyState(): string {\n return this._readyState;\n }\n\n stop(): void {\n this.enabled = false;\n this._readyState = 'ended';\n }\n\n /**\n * Private / custom API for switching the cameras on the fly, without the\n * need for adding / removing tracks or doing any SDP renegotiation.\n *\n * This is how the reference application (AppRTCMobile) implements camera\n * switching.\n *\n * @deprecated Use applyConstraints instead.\n */\n _switchCamera(): void {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n const constraints = deepClone(this._settings);\n\n delete constraints.deviceId;\n constraints.facingMode = this._settings.facingMode === 'user' ? 'environment' : 'user';\n\n this.applyConstraints(constraints);\n }\n\n _setVideoEffects(names: string[]) {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVideoEffects(this.id, names);\n }\n\n _setVideoEffect(name: string) {\n this._setVideoEffects([ name ]);\n }\n\n /**\n * Internal function which is used to set the muted state on remote tracks and\n * emit the mute / unmute event.\n *\n * @param muted Whether the track should be marked as muted / unmuted.\n */\n _setMutedInternal(muted: boolean) {\n if (!this.remote) {\n throw new Error('Track is not remote!');\n }\n\n this._muted = muted;\n this.dispatchEvent(new Event(muted ? 'mute' : 'unmute'));\n }\n\n /**\n * Custom API for setting the volume on an individual audio track.\n *\n * @param volume a gain value in the range of 0-10. defaults to 1.0\n */\n _setVolume(volume: number) {\n if (this.kind !== 'audio') {\n throw new Error('Only implemented for audio tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVolume(this.remote ? this._peerConnectionId : -1, this.id, volume);\n }\n\n /**\n * Applies a new set of constraints to the track.\n *\n * @param constraints An object listing the constraints\n * to apply to the track's constrainable properties; any existing\n * constraints are replaced with the new values specified, and any\n * constrainable properties not included are restored to their default\n * constraints. If this parameter is omitted, all currently set custom\n * constraints are cleared.\n */\n async applyConstraints(constraints?: MediaTrackConstraints): Promise<void> {\n if (this.kind !== 'video') {\n log.info(`Only implemented for video tracks, ignoring applyConstraints for ${this.id}`);\n\n return;\n }\n\n const normalized = normalizeConstraints({ video: constraints ?? true });\n\n this._settings = await WebRTCModule.mediaStreamTrackApplyConstraints(this.id, normalized.video);\n this._constraints = constraints ?? {};\n }\n\n clone(): never {\n throw new Error('Not implemented.');\n }\n\n getCapabilities(): never {\n throw new Error('Not implemented.');\n }\n\n getConstraints() {\n return deepClone(this._constraints);\n }\n\n getSettings(): MediaTrackSettings {\n return deepClone(this._settings);\n }\n\n _registerEvents(): void {\n addListener(this, 'mediaStreamTrackEnded', (ev: any) => {\n if (ev.trackId !== this.id || this._readyState === 'ended') {\n return;\n }\n\n log.debug(`${this.id} mediaStreamTrackEnded`);\n this._readyState = 'ended';\n\n this.dispatchEvent(new Event('ended'));\n });\n }\n\n private _audioSinkCallback: AudioSinkCallback | null = null;\n private _audioSinkListenerActive: boolean = false;\n private _playbackEnabled: boolean = true;\n\n _setAudioSinkCallback(callback: AudioSinkCallback | null): void {\n this._audioSinkCallback = callback;\n }\n\n _handleAudioSamples(data: AudioSampleData): void {\n if (this._audioSinkCallback) {\n this._audioSinkCallback(data);\n }\n }\n\n setAudioSink(callback: AudioSinkCallback | null): void {\n if (this.kind !== 'audio') {\n throw new Error('Audio sink only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Audio sink only available for remote tracks');\n }\n\n this._setAudioSinkCallback(callback);\n\n if (callback && !this._audioSinkListenerActive) {\n this._audioSinkListenerActive = true;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n true\n );\n addListener(this, 'audioSamples', (ev: any) => {\n if (ev.trackId === this.id) {\n this._handleAudioSamples(ev);\n }\n });\n } else if (!callback && this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n }\n\n setPlaybackEnabled(enabled: boolean): void {\n if (this.kind !== 'audio') {\n throw new Error('Playback control only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Playback control only available for remote tracks');\n }\n\n this._playbackEnabled = enabled;\n WebRTCModule.mediaStreamTrackSetPlaybackEnabled(\n this._peerConnectionId,\n this.id,\n enabled\n );\n }\n\n isPlaybackEnabled(): boolean {\n return this._playbackEnabled;\n }\n\n release(): void {\n if (this.remote) {\n if (this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n return;\n }\n\n removeListener(this);\n WebRTCModule.mediaStreamTrackRelease(this.id);\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaStreamTrack.prototype;\n\ndefineEventAttribute(proto, 'ended');\ndefineEventAttribute(proto, 'mute');\ndefineEventAttribute(proto, 'unmute');\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_index","require","_reactNative","_EventEmitter","_Logger","_interopRequireDefault","_RTCUtil","obj","__esModule","default","_defineProperty","key","value","Object","defineProperty","enumerable","configurable","writable","log","Logger","WebRTCModule","NativeModules","MediaStreamTrack","EventTarget","constructor","info","_constraints","constraints","_enabled","enabled","_settings","settings","_muted","_peerConnectionId","peerConnectionId","_readyState","readyState","id","kind","remote","_registerEvents","Boolean","mediaStreamTrackSetEnabled","muted","stop","_switchCamera","Error","deepClone","deviceId","facingMode","applyConstraints","_setVideoEffects","names","mediaStreamTrackSetVideoEffects","_setVideoEffect","name","_setMutedInternal","dispatchEvent","Event","_setVolume","volume","mediaStreamTrackSetVolume","normalized","normalizeConstraints","video","mediaStreamTrackApplyConstraints","clone","getCapabilities","getConstraints","getSettings","addListener","ev","trackId","debug","_setAudioSinkCallback","callback","_audioSinkCallback","_handleAudioSamples","data","setAudioSink","_audioSinkListenerActive","mediaStreamTrackEnableAudioSink","removeListenerForEvent","setPlaybackEnabled","_playbackEnabled","mediaStreamTrackSetPlaybackEnabled","isPlaybackEnabled","release","removeListener","mediaStreamTrackRelease","exports","proto","prototype","defineEventAttribute"],"sources":["MediaStreamTrack.ts"],"sourcesContent":["import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index';\nimport { NativeModules } from 'react-native';\n\nimport { MediaTrackConstraints } from './Constraints';\nimport { addListener, removeListener, removeListenerForEvent } from './EventEmitter';\nimport Logger from './Logger';\nimport { deepClone, normalizeConstraints } from './RTCUtil';\n\nconst log = new Logger('pc');\nconst { WebRTCModule } = NativeModules;\n\nexport type AudioSampleData = {\n trackId: string;\n samples: number[];\n sampleRate: number;\n channels: number;\n bitsPerSample: number;\n framesPerBuffer: number;\n timestamp: number;\n}\n\nexport type AudioSinkCallback = (data: AudioSampleData) => void;\n\n\ntype MediaStreamTrackState = 'live' | 'ended';\n\nexport type MediaStreamTrackInfo = {\n id: string;\n kind: string;\n remote: boolean;\n constraints: object;\n enabled: boolean;\n settings: object;\n peerConnectionId: number;\n readyState: MediaStreamTrackState;\n}\n\nexport type MediaTrackSettings = {\n width?: number;\n height?: number;\n frameRate?: number;\n facingMode?: string;\n deviceId?: string;\n groupId?: string;\n}\n\ntype MediaStreamTrackEventMap = {\n ended: Event<'ended'>;\n mute: Event<'mute'>;\n unmute: Event<'unmute'>;\n}\n\nexport default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventMap> {\n _constraints: MediaTrackConstraints;\n _enabled: boolean;\n _settings: MediaTrackSettings;\n _muted: boolean;\n _peerConnectionId: number;\n _readyState: MediaStreamTrackState;\n\n readonly id: string;\n readonly kind: string;\n readonly label: string = '';\n readonly remote: boolean;\n\n constructor(info: MediaStreamTrackInfo) {\n super();\n\n this._constraints = info.constraints || {};\n this._enabled = info.enabled;\n this._settings = info.settings || {};\n this._muted = false;\n this._peerConnectionId = info.peerConnectionId;\n this._readyState = info.readyState;\n\n this.id = info.id;\n this.kind = info.kind;\n this.remote = info.remote;\n\n if (!this.remote) {\n this._registerEvents();\n }\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(enabled: boolean) {\n if (enabled === this._enabled) {\n return;\n }\n\n this._enabled = Boolean(enabled);\n\n if (this._readyState === 'ended') {\n return;\n }\n\n WebRTCModule.mediaStreamTrackSetEnabled(this.remote ? this._peerConnectionId : -1, this.id, this._enabled);\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n get readyState(): string {\n return this._readyState;\n }\n\n stop(): void {\n this.enabled = false;\n this._readyState = 'ended';\n }\n\n /**\n * Private / custom API for switching the cameras on the fly, without the\n * need for adding / removing tracks or doing any SDP renegotiation.\n *\n * This is how the reference application (AppRTCMobile) implements camera\n * switching.\n *\n * @deprecated Use applyConstraints instead.\n */\n _switchCamera(): void {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n const constraints = deepClone(this._settings);\n\n delete constraints.deviceId;\n constraints.facingMode = this._settings.facingMode === 'user' ? 'environment' : 'user';\n\n this.applyConstraints(constraints);\n }\n\n _setVideoEffects(names: string[]) {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVideoEffects(this.id, names);\n }\n\n _setVideoEffect(name: string) {\n this._setVideoEffects([ name ]);\n }\n\n /**\n * Internal function which is used to set the muted state on remote tracks and\n * emit the mute / unmute event.\n *\n * @param muted Whether the track should be marked as muted / unmuted.\n */\n _setMutedInternal(muted: boolean) {\n if (!this.remote) {\n throw new Error('Track is not remote!');\n }\n\n this._muted = muted;\n this.dispatchEvent(new Event(muted ? 'mute' : 'unmute'));\n }\n\n /**\n * Custom API for setting the volume on an individual audio track.\n *\n * @param volume a gain value in the range of 0-10. defaults to 1.0\n */\n _setVolume(volume: number) {\n if (this.kind !== 'audio') {\n throw new Error('Only implemented for audio tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVolume(this.remote ? this._peerConnectionId : -1, this.id, volume);\n }\n\n /**\n * Applies a new set of constraints to the track.\n *\n * @param constraints An object listing the constraints\n * to apply to the track's constrainable properties; any existing\n * constraints are replaced with the new values specified, and any\n * constrainable properties not included are restored to their default\n * constraints. If this parameter is omitted, all currently set custom\n * constraints are cleared.\n */\n async applyConstraints(constraints?: MediaTrackConstraints): Promise<void> {\n if (this.kind !== 'video') {\n log.info(`Only implemented for video tracks, ignoring applyConstraints for ${this.id}`);\n\n return;\n }\n\n const normalized = normalizeConstraints({ video: constraints ?? true });\n\n this._settings = await WebRTCModule.mediaStreamTrackApplyConstraints(this.id, normalized.video);\n this._constraints = constraints ?? {};\n }\n\n clone(): never {\n throw new Error('Not implemented.');\n }\n\n getCapabilities(): never {\n throw new Error('Not implemented.');\n }\n\n getConstraints() {\n return deepClone(this._constraints);\n }\n\n getSettings(): MediaTrackSettings {\n return deepClone(this._settings);\n }\n\n _registerEvents(): void {\n addListener(this, 'mediaStreamTrackEnded', (ev: any) => {\n if (ev.trackId !== this.id || this._readyState === 'ended') {\n return;\n }\n\n log.debug(`${this.id} mediaStreamTrackEnded`);\n this._readyState = 'ended';\n\n this.dispatchEvent(new Event('ended'));\n });\n }\n\n private _audioSinkCallback: AudioSinkCallback | null = null;\n private _audioSinkListenerActive = false;\n private _playbackEnabled = true;\n\n _setAudioSinkCallback(callback: AudioSinkCallback | null): void {\n this._audioSinkCallback = callback;\n }\n\n _handleAudioSamples(data: AudioSampleData): void {\n if (this._audioSinkCallback) {\n this._audioSinkCallback(data);\n }\n }\n\n setAudioSink(callback: AudioSinkCallback | null): void {\n if (this.kind !== 'audio') {\n throw new Error('Audio sink only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Audio sink only available for remote tracks');\n }\n\n this._setAudioSinkCallback(callback);\n\n if (callback && !this._audioSinkListenerActive) {\n this._audioSinkListenerActive = true;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n true\n );\n addListener(this, 'audioSamples', (ev: any) => {\n if (ev.trackId === this.id) {\n this._handleAudioSamples(ev);\n }\n });\n } else if (!callback && this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n }\n\n setPlaybackEnabled(enabled: boolean): void {\n if (this.kind !== 'audio') {\n throw new Error('Playback control only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Playback control only available for remote tracks');\n }\n\n this._playbackEnabled = enabled;\n WebRTCModule.mediaStreamTrackSetPlaybackEnabled(\n this._peerConnectionId,\n this.id,\n enabled\n );\n }\n\n isPlaybackEnabled(): boolean {\n return this._playbackEnabled;\n }\n\n release(): void {\n if (this.remote) {\n if (this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n\n return;\n }\n\n removeListener(this);\n WebRTCModule.mediaStreamTrackRelease(this.id);\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaStreamTrack.prototype;\n\ndefineEventAttribute(proto, 'ended');\ndefineEventAttribute(proto, 'mute');\ndefineEventAttribute(proto, 'unmute');\n"],"mappings":"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"}
|
|
@@ -40,7 +40,9 @@ export function removeListener(listener) {
|
|
|
40
40
|
}
|
|
41
41
|
export function removeListenerForEvent(listener, eventName) {
|
|
42
42
|
const subs = _subscriptions.get(listener);
|
|
43
|
-
if (!subs)
|
|
43
|
+
if (!subs) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
44
46
|
const remaining = [];
|
|
45
47
|
subs.forEach(sub => {
|
|
46
48
|
if (sub.eventType === eventName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","NativeEventEmitter","EventEmitter","WebRTCModule","nativeEmitter","NATIVE_EVENTS","eventEmitter","setupNativeEvents","eventName","addListener","_len","arguments","length","args","Array","_key","emit","_subscriptions","Map","listener","eventHandler","_subscriptions$get","includes","Error","has","set","get","push","removeListener","_subscriptions$get2","forEach","sub","remove","delete","removeListenerForEvent","subs","remaining","eventType"],"sources":["EventEmitter.ts"],"sourcesContent":["import { NativeModules, NativeEventEmitter, EmitterSubscription } from 'react-native';\n// @ts-ignore\nimport EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';\n\nconst { WebRTCModule } = NativeModules;\n\n// This emitter is going to be used to listen to all the native events (once) and then\n// re-emit them on a JS-only emitter.\nconst nativeEmitter = new NativeEventEmitter(WebRTCModule);\n\nconst NATIVE_EVENTS = [\n 'peerConnectionSignalingStateChanged',\n 'peerConnectionStateChanged',\n 'peerConnectionOnRenegotiationNeeded',\n 'peerConnectionIceConnectionChanged',\n 'peerConnectionIceGatheringChanged',\n 'peerConnectionGotICECandidate',\n 'peerConnectionDidOpenDataChannel',\n 'peerConnectionOnRemoveTrack',\n 'peerConnectionOnTrack',\n 'dataChannelStateChanged',\n 'dataChannelReceiveMessage',\n 'dataChannelDidChangeBufferedAmount',\n 'mediaStreamTrackMuteChanged',\n 'mediaStreamTrackEnded',\n 'frameCryptionStateChanged',\n 'audioSamples',\n];\n\nconst eventEmitter = new EventEmitter();\n\nexport function setupNativeEvents() {\n for (const eventName of NATIVE_EVENTS) {\n nativeEmitter.addListener(eventName, (...args) => {\n eventEmitter.emit(eventName, ...args);\n });\n }\n}\n\ntype EventHandler = (event: unknown) => void;\ntype Listener = unknown;\n\nconst _subscriptions: Map<Listener, EmitterSubscription[]> = new Map();\n\nexport function addListener(listener: Listener, eventName: string, eventHandler: EventHandler): void {\n if (!NATIVE_EVENTS.includes(eventName)) {\n throw new Error(`Invalid event: ${eventName}`);\n }\n\n if (!_subscriptions.has(listener)) {\n _subscriptions.set(listener, []);\n }\n\n _subscriptions.get(listener)?.push(eventEmitter.addListener(eventName, eventHandler));\n}\n\nexport function removeListener(listener: Listener): void {\n _subscriptions.get(listener)?.forEach(sub => {\n sub.remove();\n });\n\n _subscriptions.delete(listener);\n}\n\nexport function removeListenerForEvent(listener: Listener, eventName: string): void {\n const subs = _subscriptions.get(listener);\n if (!subs) return;\n \n const remaining: EmitterSubscription[] = [];\n subs.forEach(sub => {\n if ((sub as any).eventType === eventName) {\n sub.remove();\n } else {\n remaining.push(sub);\n }\n });\n
|
|
1
|
+
{"version":3,"names":["NativeModules","NativeEventEmitter","EventEmitter","WebRTCModule","nativeEmitter","NATIVE_EVENTS","eventEmitter","setupNativeEvents","eventName","addListener","_len","arguments","length","args","Array","_key","emit","_subscriptions","Map","listener","eventHandler","_subscriptions$get","includes","Error","has","set","get","push","removeListener","_subscriptions$get2","forEach","sub","remove","delete","removeListenerForEvent","subs","remaining","eventType"],"sources":["EventEmitter.ts"],"sourcesContent":["import { NativeModules, NativeEventEmitter, EmitterSubscription } from 'react-native';\n// @ts-ignore\nimport EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';\n\nconst { WebRTCModule } = NativeModules;\n\n// This emitter is going to be used to listen to all the native events (once) and then\n// re-emit them on a JS-only emitter.\nconst nativeEmitter = new NativeEventEmitter(WebRTCModule);\n\nconst NATIVE_EVENTS = [\n 'peerConnectionSignalingStateChanged',\n 'peerConnectionStateChanged',\n 'peerConnectionOnRenegotiationNeeded',\n 'peerConnectionIceConnectionChanged',\n 'peerConnectionIceGatheringChanged',\n 'peerConnectionGotICECandidate',\n 'peerConnectionDidOpenDataChannel',\n 'peerConnectionOnRemoveTrack',\n 'peerConnectionOnTrack',\n 'dataChannelStateChanged',\n 'dataChannelReceiveMessage',\n 'dataChannelDidChangeBufferedAmount',\n 'mediaStreamTrackMuteChanged',\n 'mediaStreamTrackEnded',\n 'frameCryptionStateChanged',\n 'audioSamples',\n];\n\nconst eventEmitter = new EventEmitter();\n\nexport function setupNativeEvents() {\n for (const eventName of NATIVE_EVENTS) {\n nativeEmitter.addListener(eventName, (...args) => {\n eventEmitter.emit(eventName, ...args);\n });\n }\n}\n\ntype EventHandler = (event: unknown) => void;\ntype Listener = unknown;\n\nconst _subscriptions: Map<Listener, EmitterSubscription[]> = new Map();\n\nexport function addListener(listener: Listener, eventName: string, eventHandler: EventHandler): void {\n if (!NATIVE_EVENTS.includes(eventName)) {\n throw new Error(`Invalid event: ${eventName}`);\n }\n\n if (!_subscriptions.has(listener)) {\n _subscriptions.set(listener, []);\n }\n\n _subscriptions.get(listener)?.push(eventEmitter.addListener(eventName, eventHandler));\n}\n\nexport function removeListener(listener: Listener): void {\n _subscriptions.get(listener)?.forEach(sub => {\n sub.remove();\n });\n\n _subscriptions.delete(listener);\n}\n\nexport function removeListenerForEvent(listener: Listener, eventName: string): void {\n const subs = _subscriptions.get(listener);\n\n if (!subs) {\n return;\n }\n\n const remaining: EmitterSubscription[] = [];\n\n subs.forEach(sub => {\n if ((sub as any).eventType === eventName) {\n sub.remove();\n } else {\n remaining.push(sub);\n }\n });\n\n if (remaining.length === 0) {\n _subscriptions.delete(listener);\n } else {\n _subscriptions.set(listener, remaining);\n }\n}\n"],"mappings":"AAAA,SAASA,aAAa,EAAEC,kBAAkB,QAA6B,cAAc;AACrF;AACA,OAAOC,YAAY,MAAM,oDAAoD;AAE7E,MAAM;EAAEC;AAAa,CAAC,GAAGH,aAAa;;AAEtC;AACA;AACA,MAAMI,aAAa,GAAG,IAAIH,kBAAkB,CAACE,YAAY,CAAC;AAE1D,MAAME,aAAa,GAAG,CAClB,qCAAqC,EACrC,4BAA4B,EAC5B,qCAAqC,EACrC,oCAAoC,EACpC,mCAAmC,EACnC,+BAA+B,EAC/B,kCAAkC,EAClC,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,oCAAoC,EACpC,6BAA6B,EAC7B,uBAAuB,EACvB,2BAA2B,EAC3B,cAAc,CACjB;AAED,MAAMC,YAAY,GAAG,IAAIJ,YAAY,CAAC,CAAC;AAEvC,OAAO,SAASK,iBAAiBA,CAAA,EAAG;EAChC,KAAK,MAAMC,SAAS,IAAIH,aAAa,EAAE;IACnCD,aAAa,CAACK,WAAW,CAACD,SAAS,EAAE,YAAa;MAAA,SAAAE,IAAA,GAAAC,SAAA,CAAAC,MAAA,EAATC,IAAI,OAAAC,KAAA,CAAAJ,IAAA,GAAAK,IAAA,MAAAA,IAAA,GAAAL,IAAA,EAAAK,IAAA;QAAJF,IAAI,CAAAE,IAAA,IAAAJ,SAAA,CAAAI,IAAA;MAAA;MACzCT,YAAY,CAACU,IAAI,CAACR,SAAS,EAAE,GAAGK,IAAI,CAAC;IACzC,CAAC,CAAC;EACN;AACJ;AAKA,MAAMI,cAAoD,GAAG,IAAIC,GAAG,CAAC,CAAC;AAEtE,OAAO,SAAST,WAAWA,CAACU,QAAkB,EAAEX,SAAiB,EAAEY,YAA0B,EAAQ;EAAA,IAAAC,kBAAA;EACjG,IAAI,CAAChB,aAAa,CAACiB,QAAQ,CAACd,SAAS,CAAC,EAAE;IACpC,MAAM,IAAIe,KAAK,CAAE,kBAAiBf,SAAU,EAAC,CAAC;EAClD;EAEA,IAAI,CAACS,cAAc,CAACO,GAAG,CAACL,QAAQ,CAAC,EAAE;IAC/BF,cAAc,CAACQ,GAAG,CAACN,QAAQ,EAAE,EAAE,CAAC;EACpC;EAEA,CAAAE,kBAAA,GAAAJ,cAAc,CAACS,GAAG,CAACP,QAAQ,CAAC,cAAAE,kBAAA,uBAA5BA,kBAAA,CAA8BM,IAAI,CAACrB,YAAY,CAACG,WAAW,CAACD,SAAS,EAAEY,YAAY,CAAC,CAAC;AACzF;AAEA,OAAO,SAASQ,cAAcA,CAACT,QAAkB,EAAQ;EAAA,IAAAU,mBAAA;EACrD,CAAAA,mBAAA,GAAAZ,cAAc,CAACS,GAAG,CAACP,QAAQ,CAAC,cAAAU,mBAAA,uBAA5BA,mBAAA,CAA8BC,OAAO,CAACC,GAAG,IAAI;IACzCA,GAAG,CAACC,MAAM,CAAC,CAAC;EAChB,CAAC,CAAC;EAEFf,cAAc,CAACgB,MAAM,CAACd,QAAQ,CAAC;AACnC;AAEA,OAAO,SAASe,sBAAsBA,CAACf,QAAkB,EAAEX,SAAiB,EAAQ;EAChF,MAAM2B,IAAI,GAAGlB,cAAc,CAACS,GAAG,CAACP,QAAQ,CAAC;EAEzC,IAAI,CAACgB,IAAI,EAAE;IACP;EACJ;EAEA,MAAMC,SAAgC,GAAG,EAAE;EAE3CD,IAAI,CAACL,OAAO,CAACC,GAAG,IAAI;IAChB,IAAKA,GAAG,CAASM,SAAS,KAAK7B,SAAS,EAAE;MACtCuB,GAAG,CAACC,MAAM,CAAC,CAAC;IAChB,CAAC,MAAM;MACHI,SAAS,CAACT,IAAI,CAACI,GAAG,CAAC;IACvB;EACJ,CAAC,CAAC;EAEF,IAAIK,SAAS,CAACxB,MAAM,KAAK,CAAC,EAAE;IACxBK,cAAc,CAACgB,MAAM,CAACd,QAAQ,CAAC;EACnC,CAAC,MAAM;IACHF,cAAc,CAACQ,GAAG,CAACN,QAAQ,EAAEiB,SAAS,CAAC;EAC3C;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["EventTarget","Event","defineEventAttribute","NativeModules","addListener","removeListener","removeListenerForEvent","Logger","deepClone","normalizeConstraints","log","WebRTCModule","MediaStreamTrack","constructor","info","_defineProperty","_constraints","constraints","_enabled","enabled","_settings","settings","_muted","_peerConnectionId","peerConnectionId","_readyState","readyState","id","kind","remote","_registerEvents","Boolean","mediaStreamTrackSetEnabled","muted","stop","_switchCamera","Error","deviceId","facingMode","applyConstraints","_setVideoEffects","names","mediaStreamTrackSetVideoEffects","_setVideoEffect","name","_setMutedInternal","dispatchEvent","_setVolume","volume","mediaStreamTrackSetVolume","normalized","video","mediaStreamTrackApplyConstraints","clone","getCapabilities","getConstraints","getSettings","ev","trackId","debug","_setAudioSinkCallback","callback","_audioSinkCallback","_handleAudioSamples","data","setAudioSink","_audioSinkListenerActive","mediaStreamTrackEnableAudioSink","setPlaybackEnabled","_playbackEnabled","mediaStreamTrackSetPlaybackEnabled","isPlaybackEnabled","release","mediaStreamTrackRelease","proto","prototype"],"sources":["MediaStreamTrack.ts"],"sourcesContent":["import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index';\nimport { NativeModules, NativeEventEmitter, Platform } from 'react-native';\n\nimport { MediaTrackConstraints } from './Constraints';\nimport { addListener, removeListener, removeListenerForEvent } from './EventEmitter';\nimport Logger from './Logger';\nimport { deepClone, normalizeConstraints } from './RTCUtil';\n\nconst log = new Logger('pc');\nconst { WebRTCModule } = NativeModules;\n\nexport type AudioSampleData = {\n trackId: string;\n samples: number[];\n sampleRate: number;\n channels: number;\n timestamp: number;\n}\n\nexport type AudioSinkCallback = (data: AudioSampleData) => void;\n\n\ntype MediaStreamTrackState = 'live' | 'ended';\n\nexport type MediaStreamTrackInfo = {\n id: string;\n kind: string;\n remote: boolean;\n constraints: object;\n enabled: boolean;\n settings: object;\n peerConnectionId: number;\n readyState: MediaStreamTrackState;\n}\n\nexport type MediaTrackSettings = {\n width?: number;\n height?: number;\n frameRate?: number;\n facingMode?: string;\n deviceId?: string;\n groupId?: string;\n}\n\ntype MediaStreamTrackEventMap = {\n ended: Event<'ended'>;\n mute: Event<'mute'>;\n unmute: Event<'unmute'>;\n}\n\nexport default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventMap> {\n _constraints: MediaTrackConstraints;\n _enabled: boolean;\n _settings: MediaTrackSettings;\n _muted: boolean;\n _peerConnectionId: number;\n _readyState: MediaStreamTrackState;\n\n readonly id: string;\n readonly kind: string;\n readonly label: string = '';\n readonly remote: boolean;\n\n constructor(info: MediaStreamTrackInfo) {\n super();\n\n this._constraints = info.constraints || {};\n this._enabled = info.enabled;\n this._settings = info.settings || {};\n this._muted = false;\n this._peerConnectionId = info.peerConnectionId;\n this._readyState = info.readyState;\n\n this.id = info.id;\n this.kind = info.kind;\n this.remote = info.remote;\n\n if (!this.remote) {\n this._registerEvents();\n }\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(enabled: boolean) {\n if (enabled === this._enabled) {\n return;\n }\n\n this._enabled = Boolean(enabled);\n\n if (this._readyState === 'ended') {\n return;\n }\n\n WebRTCModule.mediaStreamTrackSetEnabled(this.remote ? this._peerConnectionId : -1, this.id, this._enabled);\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n get readyState(): string {\n return this._readyState;\n }\n\n stop(): void {\n this.enabled = false;\n this._readyState = 'ended';\n }\n\n /**\n * Private / custom API for switching the cameras on the fly, without the\n * need for adding / removing tracks or doing any SDP renegotiation.\n *\n * This is how the reference application (AppRTCMobile) implements camera\n * switching.\n *\n * @deprecated Use applyConstraints instead.\n */\n _switchCamera(): void {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n const constraints = deepClone(this._settings);\n\n delete constraints.deviceId;\n constraints.facingMode = this._settings.facingMode === 'user' ? 'environment' : 'user';\n\n this.applyConstraints(constraints);\n }\n\n _setVideoEffects(names: string[]) {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVideoEffects(this.id, names);\n }\n\n _setVideoEffect(name: string) {\n this._setVideoEffects([ name ]);\n }\n\n /**\n * Internal function which is used to set the muted state on remote tracks and\n * emit the mute / unmute event.\n *\n * @param muted Whether the track should be marked as muted / unmuted.\n */\n _setMutedInternal(muted: boolean) {\n if (!this.remote) {\n throw new Error('Track is not remote!');\n }\n\n this._muted = muted;\n this.dispatchEvent(new Event(muted ? 'mute' : 'unmute'));\n }\n\n /**\n * Custom API for setting the volume on an individual audio track.\n *\n * @param volume a gain value in the range of 0-10. defaults to 1.0\n */\n _setVolume(volume: number) {\n if (this.kind !== 'audio') {\n throw new Error('Only implemented for audio tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVolume(this.remote ? this._peerConnectionId : -1, this.id, volume);\n }\n\n /**\n * Applies a new set of constraints to the track.\n *\n * @param constraints An object listing the constraints\n * to apply to the track's constrainable properties; any existing\n * constraints are replaced with the new values specified, and any\n * constrainable properties not included are restored to their default\n * constraints. If this parameter is omitted, all currently set custom\n * constraints are cleared.\n */\n async applyConstraints(constraints?: MediaTrackConstraints): Promise<void> {\n if (this.kind !== 'video') {\n log.info(`Only implemented for video tracks, ignoring applyConstraints for ${this.id}`);\n\n return;\n }\n\n const normalized = normalizeConstraints({ video: constraints ?? true });\n\n this._settings = await WebRTCModule.mediaStreamTrackApplyConstraints(this.id, normalized.video);\n this._constraints = constraints ?? {};\n }\n\n clone(): never {\n throw new Error('Not implemented.');\n }\n\n getCapabilities(): never {\n throw new Error('Not implemented.');\n }\n\n getConstraints() {\n return deepClone(this._constraints);\n }\n\n getSettings(): MediaTrackSettings {\n return deepClone(this._settings);\n }\n\n _registerEvents(): void {\n addListener(this, 'mediaStreamTrackEnded', (ev: any) => {\n if (ev.trackId !== this.id || this._readyState === 'ended') {\n return;\n }\n\n log.debug(`${this.id} mediaStreamTrackEnded`);\n this._readyState = 'ended';\n\n this.dispatchEvent(new Event('ended'));\n });\n }\n\n private _audioSinkCallback: AudioSinkCallback | null = null;\n private _audioSinkListenerActive: boolean = false;\n private _playbackEnabled: boolean = true;\n\n _setAudioSinkCallback(callback: AudioSinkCallback | null): void {\n this._audioSinkCallback = callback;\n }\n\n _handleAudioSamples(data: AudioSampleData): void {\n if (this._audioSinkCallback) {\n this._audioSinkCallback(data);\n }\n }\n\n setAudioSink(callback: AudioSinkCallback | null): void {\n if (this.kind !== 'audio') {\n throw new Error('Audio sink only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Audio sink only available for remote tracks');\n }\n\n this._setAudioSinkCallback(callback);\n\n if (callback && !this._audioSinkListenerActive) {\n this._audioSinkListenerActive = true;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n true\n );\n addListener(this, 'audioSamples', (ev: any) => {\n if (ev.trackId === this.id) {\n this._handleAudioSamples(ev);\n }\n });\n } else if (!callback && this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n }\n\n setPlaybackEnabled(enabled: boolean): void {\n if (this.kind !== 'audio') {\n throw new Error('Playback control only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Playback control only available for remote tracks');\n }\n\n this._playbackEnabled = enabled;\n WebRTCModule.mediaStreamTrackSetPlaybackEnabled(\n this._peerConnectionId,\n this.id,\n enabled\n );\n }\n\n isPlaybackEnabled(): boolean {\n return this._playbackEnabled;\n }\n\n release(): void {\n if (this.remote) {\n if (this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n return;\n }\n\n removeListener(this);\n WebRTCModule.mediaStreamTrackRelease(this.id);\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaStreamTrack.prototype;\n\ndefineEventAttribute(proto, 'ended');\ndefineEventAttribute(proto, 'mute');\ndefineEventAttribute(proto, 'unmute');\n"],"mappings":";AAAA,SAASA,WAAW,EAAEC,KAAK,EAAEC,oBAAoB,QAAQ,yBAAyB;AAClF,SAASC,aAAa,QAAsC,cAAc;AAG1E,SAASC,WAAW,EAAEC,cAAc,EAAEC,sBAAsB,QAAQ,gBAAgB;AACpF,OAAOC,MAAM,MAAM,UAAU;AAC7B,SAASC,SAAS,EAAEC,oBAAoB,QAAQ,WAAW;AAE3D,MAAMC,GAAG,GAAG,IAAIH,MAAM,CAAC,IAAI,CAAC;AAC5B,MAAM;EAAEI;AAAa,CAAC,GAAGR,aAAa;AAyCtC,eAAe,MAAMS,gBAAgB,SAASZ,WAAW,CAA2B;EAahFa,WAAWA,CAACC,IAA0B,EAAE;IACpC,KAAK,CAAC,CAAC;IAACC,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA,gBAJa,EAAE;IAAAA,eAAA;IAAAA,eAAA,6BA+K4B,IAAI;IAAAA,eAAA,mCACf,KAAK;IAAAA,eAAA,2BACb,IAAI;IA3KpC,IAAI,CAACC,YAAY,GAAGF,IAAI,CAACG,WAAW,IAAI,CAAC,CAAC;IAC1C,IAAI,CAACC,QAAQ,GAAGJ,IAAI,CAACK,OAAO;IAC5B,IAAI,CAACC,SAAS,GAAGN,IAAI,CAACO,QAAQ,IAAI,CAAC,CAAC;IACpC,IAAI,CAACC,MAAM,GAAG,KAAK;IACnB,IAAI,CAACC,iBAAiB,GAAGT,IAAI,CAACU,gBAAgB;IAC9C,IAAI,CAACC,WAAW,GAAGX,IAAI,CAACY,UAAU;IAElC,IAAI,CAACC,EAAE,GAAGb,IAAI,CAACa,EAAE;IACjB,IAAI,CAACC,IAAI,GAAGd,IAAI,CAACc,IAAI;IACrB,IAAI,CAACC,MAAM,GAAGf,IAAI,CAACe,MAAM;IAEzB,IAAI,CAAC,IAAI,CAACA,MAAM,EAAE;MACd,IAAI,CAACC,eAAe,CAAC,CAAC;IAC1B;EACJ;EAEA,IAAIX,OAAOA,CAAA,EAAY;IACnB,OAAO,IAAI,CAACD,QAAQ;EACxB;EAEA,IAAIC,OAAOA,CAACA,OAAgB,EAAE;IAC1B,IAAIA,OAAO,KAAK,IAAI,CAACD,QAAQ,EAAE;MAC3B;IACJ;IAEA,IAAI,CAACA,QAAQ,GAAGa,OAAO,CAACZ,OAAO,CAAC;IAEhC,IAAI,IAAI,CAACM,WAAW,KAAK,OAAO,EAAE;MAC9B;IACJ;IAEAd,YAAY,CAACqB,0BAA0B,CAAC,IAAI,CAACH,MAAM,GAAG,IAAI,CAACN,iBAAiB,GAAG,CAAC,CAAC,EAAE,IAAI,CAACI,EAAE,EAAE,IAAI,CAACT,QAAQ,CAAC;EAC9G;EAEA,IAAIe,KAAKA,CAAA,EAAY;IACjB,OAAO,IAAI,CAACX,MAAM;EACtB;EAEA,IAAII,UAAUA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACD,WAAW;EAC3B;EAEAS,IAAIA,CAAA,EAAS;IACT,IAAI,CAACf,OAAO,GAAG,KAAK;IACpB,IAAI,CAACM,WAAW,GAAG,OAAO;EAC9B;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACIU,aAAaA,CAAA,EAAS;IAClB,IAAI,IAAI,CAACN,MAAM,EAAE;MACb,MAAM,IAAIO,KAAK,CAAC,mCAAmC,CAAC;IACxD;IAEA,IAAI,IAAI,CAACR,IAAI,KAAK,OAAO,EAAE;MACvB,MAAM,IAAIQ,KAAK,CAAC,mCAAmC,CAAC;IACxD;IAEA,MAAMnB,WAAW,GAAGT,SAAS,CAAC,IAAI,CAACY,SAAS,CAAC;IAE7C,OAAOH,WAAW,CAACoB,QAAQ;IAC3BpB,WAAW,CAACqB,UAAU,GAAG,IAAI,CAAClB,SAAS,CAACkB,UAAU,KAAK,MAAM,GAAG,aAAa,GAAG,MAAM;IAEtF,IAAI,CAACC,gBAAgB,CAACtB,WAAW,CAAC;EACtC;EAEAuB,gBAAgBA,CAACC,KAAe,EAAE;IAC9B,IAAI,IAAI,CAACZ,MAAM,EAAE;MACb,MAAM,IAAIO,KAAK,CAAC,mCAAmC,CAAC;IACxD;IAEA,IAAI,IAAI,CAACR,IAAI,KAAK,OAAO,EAAE;MACvB,MAAM,IAAIQ,KAAK,CAAC,mCAAmC,CAAC;IACxD;IAEAzB,YAAY,CAAC+B,+BAA+B,CAAC,IAAI,CAACf,EAAE,EAAEc,KAAK,CAAC;EAChE;EAEAE,eAAeA,CAACC,IAAY,EAAE;IAC1B,IAAI,CAACJ,gBAAgB,CAAC,CAAEI,IAAI,CAAE,CAAC;EACnC;;EAEA;AACJ;AACA;AACA;AACA;AACA;EACIC,iBAAiBA,CAACZ,KAAc,EAAE;IAC9B,IAAI,CAAC,IAAI,CAACJ,MAAM,EAAE;MACd,MAAM,IAAIO,KAAK,CAAC,sBAAsB,CAAC;IAC3C;IAEA,IAAI,CAACd,MAAM,GAAGW,KAAK;IACnB,IAAI,CAACa,aAAa,CAAC,IAAI7C,KAAK,CAACgC,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;EAC5D;;EAEA;AACJ;AACA;AACA;AACA;EACIc,UAAUA,CAACC,MAAc,EAAE;IACvB,IAAI,IAAI,CAACpB,IAAI,KAAK,OAAO,EAAE;MACvB,MAAM,IAAIQ,KAAK,CAAC,mCAAmC,CAAC;IACxD;IAEAzB,YAAY,CAACsC,yBAAyB,CAAC,IAAI,CAACpB,MAAM,GAAG,IAAI,CAACN,iBAAiB,GAAG,CAAC,CAAC,EAAE,IAAI,CAACI,EAAE,EAAEqB,MAAM,CAAC;EACtG;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMT,gBAAgBA,CAACtB,WAAmC,EAAiB;IACvE,IAAI,IAAI,CAACW,IAAI,KAAK,OAAO,EAAE;MACvBlB,GAAG,CAACI,IAAI,CAAE,oEAAmE,IAAI,CAACa,EAAG,EAAC,CAAC;MAEvF;IACJ;IAEA,MAAMuB,UAAU,GAAGzC,oBAAoB,CAAC;MAAE0C,KAAK,EAAElC,WAAW,aAAXA,WAAW,cAAXA,WAAW,GAAI;IAAK,CAAC,CAAC;IAEvE,IAAI,CAACG,SAAS,GAAG,MAAMT,YAAY,CAACyC,gCAAgC,CAAC,IAAI,CAACzB,EAAE,EAAEuB,UAAU,CAACC,KAAK,CAAC;IAC/F,IAAI,CAACnC,YAAY,GAAGC,WAAW,aAAXA,WAAW,cAAXA,WAAW,GAAI,CAAC,CAAC;EACzC;EAEAoC,KAAKA,CAAA,EAAU;IACX,MAAM,IAAIjB,KAAK,CAAC,kBAAkB,CAAC;EACvC;EAEAkB,eAAeA,CAAA,EAAU;IACrB,MAAM,IAAIlB,KAAK,CAAC,kBAAkB,CAAC;EACvC;EAEAmB,cAAcA,CAAA,EAAG;IACb,OAAO/C,SAAS,CAAC,IAAI,CAACQ,YAAY,CAAC;EACvC;EAEAwC,WAAWA,CAAA,EAAuB;IAC9B,OAAOhD,SAAS,CAAC,IAAI,CAACY,SAAS,CAAC;EACpC;EAEAU,eAAeA,CAAA,EAAS;IACpB1B,WAAW,CAAC,IAAI,EAAE,uBAAuB,EAAGqD,EAAO,IAAK;MACpD,IAAIA,EAAE,CAACC,OAAO,KAAK,IAAI,CAAC/B,EAAE,IAAI,IAAI,CAACF,WAAW,KAAK,OAAO,EAAE;QACxD;MACJ;MAEAf,GAAG,CAACiD,KAAK,CAAE,GAAE,IAAI,CAAChC,EAAG,wBAAuB,CAAC;MAC7C,IAAI,CAACF,WAAW,GAAG,OAAO;MAE1B,IAAI,CAACqB,aAAa,CAAC,IAAI7C,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC;EACN;EAMA2D,qBAAqBA,CAACC,QAAkC,EAAQ;IAC5D,IAAI,CAACC,kBAAkB,GAAGD,QAAQ;EACtC;EAEAE,mBAAmBA,CAACC,IAAqB,EAAQ;IAC7C,IAAI,IAAI,CAACF,kBAAkB,EAAE;MACzB,IAAI,CAACA,kBAAkB,CAACE,IAAI,CAAC;IACjC;EACJ;EAEAC,YAAYA,CAACJ,QAAkC,EAAQ;IACnD,IAAI,IAAI,CAACjC,IAAI,KAAK,OAAO,EAAE;MACvB,MAAM,IAAIQ,KAAK,CAAC,4CAA4C,CAAC;IACjE;IAEA,IAAI,CAAC,IAAI,CAACP,MAAM,EAAE;MACd,MAAM,IAAIO,KAAK,CAAC,6CAA6C,CAAC;IAClE;IAEA,IAAI,CAACwB,qBAAqB,CAACC,QAAQ,CAAC;IAEpC,IAAIA,QAAQ,IAAI,CAAC,IAAI,CAACK,wBAAwB,EAAE;MAC5C,IAAI,CAACA,wBAAwB,GAAG,IAAI;MACpCvD,YAAY,CAACwD,+BAA+B,CACxC,IAAI,CAAC5C,iBAAiB,EACtB,IAAI,CAACI,EAAE,EACP,IACJ,CAAC;MACDvB,WAAW,CAAC,IAAI,EAAE,cAAc,EAAGqD,EAAO,IAAK;QAC3C,IAAIA,EAAE,CAACC,OAAO,KAAK,IAAI,CAAC/B,EAAE,EAAE;UACxB,IAAI,CAACoC,mBAAmB,CAACN,EAAE,CAAC;QAChC;MACJ,CAAC,CAAC;IACN,CAAC,MAAM,IAAI,CAACI,QAAQ,IAAI,IAAI,CAACK,wBAAwB,EAAE;MACnD,IAAI,CAACA,wBAAwB,GAAG,KAAK;MACrCvD,YAAY,CAACwD,+BAA+B,CACxC,IAAI,CAAC5C,iBAAiB,EACtB,IAAI,CAACI,EAAE,EACP,KACJ,CAAC;MACDrB,sBAAsB,CAAC,IAAI,EAAE,cAAc,CAAC;IAChD;EACJ;EAEA8D,kBAAkBA,CAACjD,OAAgB,EAAQ;IACvC,IAAI,IAAI,CAACS,IAAI,KAAK,OAAO,EAAE;MACvB,MAAM,IAAIQ,KAAK,CAAC,kDAAkD,CAAC;IACvE;IAEA,IAAI,CAAC,IAAI,CAACP,MAAM,EAAE;MACd,MAAM,IAAIO,KAAK,CAAC,mDAAmD,CAAC;IACxE;IAEA,IAAI,CAACiC,gBAAgB,GAAGlD,OAAO;IAC/BR,YAAY,CAAC2D,kCAAkC,CAC3C,IAAI,CAAC/C,iBAAiB,EACtB,IAAI,CAACI,EAAE,EACPR,OACJ,CAAC;EACL;EAEAoD,iBAAiBA,CAAA,EAAY;IACzB,OAAO,IAAI,CAACF,gBAAgB;EAChC;EAEAG,OAAOA,CAAA,EAAS;IACZ,IAAI,IAAI,CAAC3C,MAAM,EAAE;MACb,IAAI,IAAI,CAACqC,wBAAwB,EAAE;QAC/B,IAAI,CAACA,wBAAwB,GAAG,KAAK;QACrCvD,YAAY,CAACwD,+BAA+B,CACxC,IAAI,CAAC5C,iBAAiB,EACtB,IAAI,CAACI,EAAE,EACP,KACJ,CAAC;QACDrB,sBAAsB,CAAC,IAAI,EAAE,cAAc,CAAC;MAChD;MACA;IACJ;IAEAD,cAAc,CAAC,IAAI,CAAC;IACpBM,YAAY,CAAC8D,uBAAuB,CAAC,IAAI,CAAC9C,EAAE,CAAC;EACjD;AACJ;;AAEA;AACA;AACA;AACA,MAAM+C,KAAK,GAAG9D,gBAAgB,CAAC+D,SAAS;AAExCzE,oBAAoB,CAACwE,KAAK,EAAE,OAAO,CAAC;AACpCxE,oBAAoB,CAACwE,KAAK,EAAE,MAAM,CAAC;AACnCxE,oBAAoB,CAACwE,KAAK,EAAE,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"names":["EventTarget","Event","defineEventAttribute","NativeModules","addListener","removeListener","removeListenerForEvent","Logger","deepClone","normalizeConstraints","log","WebRTCModule","MediaStreamTrack","constructor","info","_defineProperty","_constraints","constraints","_enabled","enabled","_settings","settings","_muted","_peerConnectionId","peerConnectionId","_readyState","readyState","id","kind","remote","_registerEvents","Boolean","mediaStreamTrackSetEnabled","muted","stop","_switchCamera","Error","deviceId","facingMode","applyConstraints","_setVideoEffects","names","mediaStreamTrackSetVideoEffects","_setVideoEffect","name","_setMutedInternal","dispatchEvent","_setVolume","volume","mediaStreamTrackSetVolume","normalized","video","mediaStreamTrackApplyConstraints","clone","getCapabilities","getConstraints","getSettings","ev","trackId","debug","_setAudioSinkCallback","callback","_audioSinkCallback","_handleAudioSamples","data","setAudioSink","_audioSinkListenerActive","mediaStreamTrackEnableAudioSink","setPlaybackEnabled","_playbackEnabled","mediaStreamTrackSetPlaybackEnabled","isPlaybackEnabled","release","mediaStreamTrackRelease","proto","prototype"],"sources":["MediaStreamTrack.ts"],"sourcesContent":["import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index';\nimport { NativeModules } from 'react-native';\n\nimport { MediaTrackConstraints } from './Constraints';\nimport { addListener, removeListener, removeListenerForEvent } from './EventEmitter';\nimport Logger from './Logger';\nimport { deepClone, normalizeConstraints } from './RTCUtil';\n\nconst log = new Logger('pc');\nconst { WebRTCModule } = NativeModules;\n\nexport type AudioSampleData = {\n trackId: string;\n samples: number[];\n sampleRate: number;\n channels: number;\n bitsPerSample: number;\n framesPerBuffer: number;\n timestamp: number;\n}\n\nexport type AudioSinkCallback = (data: AudioSampleData) => void;\n\n\ntype MediaStreamTrackState = 'live' | 'ended';\n\nexport type MediaStreamTrackInfo = {\n id: string;\n kind: string;\n remote: boolean;\n constraints: object;\n enabled: boolean;\n settings: object;\n peerConnectionId: number;\n readyState: MediaStreamTrackState;\n}\n\nexport type MediaTrackSettings = {\n width?: number;\n height?: number;\n frameRate?: number;\n facingMode?: string;\n deviceId?: string;\n groupId?: string;\n}\n\ntype MediaStreamTrackEventMap = {\n ended: Event<'ended'>;\n mute: Event<'mute'>;\n unmute: Event<'unmute'>;\n}\n\nexport default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventMap> {\n _constraints: MediaTrackConstraints;\n _enabled: boolean;\n _settings: MediaTrackSettings;\n _muted: boolean;\n _peerConnectionId: number;\n _readyState: MediaStreamTrackState;\n\n readonly id: string;\n readonly kind: string;\n readonly label: string = '';\n readonly remote: boolean;\n\n constructor(info: MediaStreamTrackInfo) {\n super();\n\n this._constraints = info.constraints || {};\n this._enabled = info.enabled;\n this._settings = info.settings || {};\n this._muted = false;\n this._peerConnectionId = info.peerConnectionId;\n this._readyState = info.readyState;\n\n this.id = info.id;\n this.kind = info.kind;\n this.remote = info.remote;\n\n if (!this.remote) {\n this._registerEvents();\n }\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(enabled: boolean) {\n if (enabled === this._enabled) {\n return;\n }\n\n this._enabled = Boolean(enabled);\n\n if (this._readyState === 'ended') {\n return;\n }\n\n WebRTCModule.mediaStreamTrackSetEnabled(this.remote ? this._peerConnectionId : -1, this.id, this._enabled);\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n get readyState(): string {\n return this._readyState;\n }\n\n stop(): void {\n this.enabled = false;\n this._readyState = 'ended';\n }\n\n /**\n * Private / custom API for switching the cameras on the fly, without the\n * need for adding / removing tracks or doing any SDP renegotiation.\n *\n * This is how the reference application (AppRTCMobile) implements camera\n * switching.\n *\n * @deprecated Use applyConstraints instead.\n */\n _switchCamera(): void {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n const constraints = deepClone(this._settings);\n\n delete constraints.deviceId;\n constraints.facingMode = this._settings.facingMode === 'user' ? 'environment' : 'user';\n\n this.applyConstraints(constraints);\n }\n\n _setVideoEffects(names: string[]) {\n if (this.remote) {\n throw new Error('Not implemented for remote tracks');\n }\n\n if (this.kind !== 'video') {\n throw new Error('Only implemented for video tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVideoEffects(this.id, names);\n }\n\n _setVideoEffect(name: string) {\n this._setVideoEffects([ name ]);\n }\n\n /**\n * Internal function which is used to set the muted state on remote tracks and\n * emit the mute / unmute event.\n *\n * @param muted Whether the track should be marked as muted / unmuted.\n */\n _setMutedInternal(muted: boolean) {\n if (!this.remote) {\n throw new Error('Track is not remote!');\n }\n\n this._muted = muted;\n this.dispatchEvent(new Event(muted ? 'mute' : 'unmute'));\n }\n\n /**\n * Custom API for setting the volume on an individual audio track.\n *\n * @param volume a gain value in the range of 0-10. defaults to 1.0\n */\n _setVolume(volume: number) {\n if (this.kind !== 'audio') {\n throw new Error('Only implemented for audio tracks');\n }\n\n WebRTCModule.mediaStreamTrackSetVolume(this.remote ? this._peerConnectionId : -1, this.id, volume);\n }\n\n /**\n * Applies a new set of constraints to the track.\n *\n * @param constraints An object listing the constraints\n * to apply to the track's constrainable properties; any existing\n * constraints are replaced with the new values specified, and any\n * constrainable properties not included are restored to their default\n * constraints. If this parameter is omitted, all currently set custom\n * constraints are cleared.\n */\n async applyConstraints(constraints?: MediaTrackConstraints): Promise<void> {\n if (this.kind !== 'video') {\n log.info(`Only implemented for video tracks, ignoring applyConstraints for ${this.id}`);\n\n return;\n }\n\n const normalized = normalizeConstraints({ video: constraints ?? true });\n\n this._settings = await WebRTCModule.mediaStreamTrackApplyConstraints(this.id, normalized.video);\n this._constraints = constraints ?? {};\n }\n\n clone(): never {\n throw new Error('Not implemented.');\n }\n\n getCapabilities(): never {\n throw new Error('Not implemented.');\n }\n\n getConstraints() {\n return deepClone(this._constraints);\n }\n\n getSettings(): MediaTrackSettings {\n return deepClone(this._settings);\n }\n\n _registerEvents(): void {\n addListener(this, 'mediaStreamTrackEnded', (ev: any) => {\n if (ev.trackId !== this.id || this._readyState === 'ended') {\n return;\n }\n\n log.debug(`${this.id} mediaStreamTrackEnded`);\n this._readyState = 'ended';\n\n this.dispatchEvent(new Event('ended'));\n });\n }\n\n private _audioSinkCallback: AudioSinkCallback | null = null;\n private _audioSinkListenerActive = false;\n private _playbackEnabled = true;\n\n _setAudioSinkCallback(callback: AudioSinkCallback | null): void {\n this._audioSinkCallback = callback;\n }\n\n _handleAudioSamples(data: AudioSampleData): void {\n if (this._audioSinkCallback) {\n this._audioSinkCallback(data);\n }\n }\n\n setAudioSink(callback: AudioSinkCallback | null): void {\n if (this.kind !== 'audio') {\n throw new Error('Audio sink only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Audio sink only available for remote tracks');\n }\n\n this._setAudioSinkCallback(callback);\n\n if (callback && !this._audioSinkListenerActive) {\n this._audioSinkListenerActive = true;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n true\n );\n addListener(this, 'audioSamples', (ev: any) => {\n if (ev.trackId === this.id) {\n this._handleAudioSamples(ev);\n }\n });\n } else if (!callback && this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n }\n\n setPlaybackEnabled(enabled: boolean): void {\n if (this.kind !== 'audio') {\n throw new Error('Playback control only available for audio tracks');\n }\n\n if (!this.remote) {\n throw new Error('Playback control only available for remote tracks');\n }\n\n this._playbackEnabled = enabled;\n WebRTCModule.mediaStreamTrackSetPlaybackEnabled(\n this._peerConnectionId,\n this.id,\n enabled\n );\n }\n\n isPlaybackEnabled(): boolean {\n return this._playbackEnabled;\n }\n\n release(): void {\n if (this.remote) {\n if (this._audioSinkListenerActive) {\n this._audioSinkListenerActive = false;\n WebRTCModule.mediaStreamTrackEnableAudioSink(\n this._peerConnectionId,\n this.id,\n false\n );\n removeListenerForEvent(this, 'audioSamples');\n }\n\n return;\n }\n\n removeListener(this);\n WebRTCModule.mediaStreamTrackRelease(this.id);\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaStreamTrack.prototype;\n\ndefineEventAttribute(proto, 'ended');\ndefineEventAttribute(proto, 'mute');\ndefineEventAttribute(proto, 'unmute');\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/EventEmitter.ts
CHANGED
|
@@ -64,9 +64,13 @@ export function removeListener(listener: Listener): void {
|
|
|
64
64
|
|
|
65
65
|
export function removeListenerForEvent(listener: Listener, eventName: string): void {
|
|
66
66
|
const subs = _subscriptions.get(listener);
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
|
|
68
|
+
if (!subs) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
69
72
|
const remaining: EmitterSubscription[] = [];
|
|
73
|
+
|
|
70
74
|
subs.forEach(sub => {
|
|
71
75
|
if ((sub as any).eventType === eventName) {
|
|
72
76
|
sub.remove();
|
|
@@ -74,7 +78,7 @@ export function removeListenerForEvent(listener: Listener, eventName: string): v
|
|
|
74
78
|
remaining.push(sub);
|
|
75
79
|
}
|
|
76
80
|
});
|
|
77
|
-
|
|
81
|
+
|
|
78
82
|
if (remaining.length === 0) {
|
|
79
83
|
_subscriptions.delete(listener);
|
|
80
84
|
} else {
|
package/src/MediaStreamTrack.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index';
|
|
2
|
-
import { NativeModules
|
|
2
|
+
import { NativeModules } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { MediaTrackConstraints } from './Constraints';
|
|
5
5
|
import { addListener, removeListener, removeListenerForEvent } from './EventEmitter';
|
|
@@ -14,6 +14,8 @@ export type AudioSampleData = {
|
|
|
14
14
|
samples: number[];
|
|
15
15
|
sampleRate: number;
|
|
16
16
|
channels: number;
|
|
17
|
+
bitsPerSample: number;
|
|
18
|
+
framesPerBuffer: number;
|
|
17
19
|
timestamp: number;
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -234,8 +236,8 @@ export default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventM
|
|
|
234
236
|
}
|
|
235
237
|
|
|
236
238
|
private _audioSinkCallback: AudioSinkCallback | null = null;
|
|
237
|
-
private _audioSinkListenerActive
|
|
238
|
-
private _playbackEnabled
|
|
239
|
+
private _audioSinkListenerActive = false;
|
|
240
|
+
private _playbackEnabled = true;
|
|
239
241
|
|
|
240
242
|
_setAudioSinkCallback(callback: AudioSinkCallback | null): void {
|
|
241
243
|
this._audioSinkCallback = callback;
|
|
@@ -313,6 +315,7 @@ export default class MediaStreamTrack extends EventTarget<MediaStreamTrackEventM
|
|
|
313
315
|
);
|
|
314
316
|
removeListenerForEvent(this, 'audioSamples');
|
|
315
317
|
}
|
|
318
|
+
|
|
316
319
|
return;
|
|
317
320
|
}
|
|
318
321
|
|