package im.actor.runtime.android.webrtc;
import org.webrtc.AudioTrack;
import org.webrtc.MediaStream;
import org.webrtc.VideoTrack;
import im.actor.runtime.android.AndroidWebRTCRuntimeProvider;
import im.actor.runtime.webrtc.WebRTCMediaStream;
import im.actor.runtime.webrtc.WebRTCMediaTrack;
public class AndroidMediaStream implements WebRTCMediaStream {
private final MediaStream stream;
private final boolean isLocal;
private AndroidVideoSource videoSource;
private AndroidAudioSource audioSource;
private AudioTrack localAudioTrack;
private VideoTrack localVideoTrack;
private final WebRTCMediaTrack[] videoTracks;
private final WebRTCMediaTrack[] audioTracks;
private final WebRTCMediaTrack[] allTracks;
public AndroidMediaStream(MediaStream stream) {
this.isLocal = false;
this.stream = stream;
this.allTracks = new WebRTCMediaTrack[stream.audioTracks.size() + stream.videoTracks.size()];
this.audioTracks = new WebRTCMediaTrack[stream.audioTracks.size()];
for (int i = 0; i < this.audioTracks.length; i++) {
audioTracks[i] = new AndroidAudioTrack(stream.audioTracks.get(i), this);
allTracks[i] = audioTracks[i];
}
this.videoTracks = new WebRTCMediaTrack[stream.videoTracks.size()];
for (int i = 0; i < this.videoTracks.length; i++) {
videoTracks[i] = new AndroidVideoTrack(stream.videoTracks.get(i), this);
allTracks[audioTracks.length + i] = videoTracks[i];
}
}
public AndroidMediaStream(AndroidAudioSource audioSource, AndroidVideoSource videoSource) {
this.isLocal = true;
this.videoSource = videoSource;
this.audioSource = audioSource;
this.stream = AndroidWebRTCRuntimeProvider.FACTORY.createLocalMediaStream("ARDAMSv0");
if (audioSource != null) {
localAudioTrack = AndroidWebRTCRuntimeProvider.FACTORY.createAudioTrack("audio0", audioSource.getAudioSource());
stream.addTrack(localAudioTrack);
audioTracks = new WebRTCMediaTrack[]{new AndroidAudioTrack(localAudioTrack, this)};
} else {
audioTracks = new WebRTCMediaTrack[0];
}
if (videoSource != null) {
localVideoTrack = AndroidWebRTCRuntimeProvider.FACTORY.createVideoTrack("video0", videoSource.getVideoSource());
stream.addPreservedTrack(localVideoTrack);
videoTracks = new WebRTCMediaTrack[]{new AndroidVideoTrack(localVideoTrack, this)};
} else {
videoTracks = new WebRTCMediaTrack[0];
}
this.allTracks = new WebRTCMediaTrack[audioTracks.length + videoTracks.length];
for (int i = 0; i < audioTracks.length; i++) {
allTracks[i] = audioTracks[i];
}
for (int i = 0; i < videoTracks.length; i++) {
allTracks[audioTracks.length + i] = videoTracks[i];
}
}
public MediaStream getStream() {
return stream;
}
@Override
public WebRTCMediaTrack[] getAudioTracks() {
return audioTracks;
}
@Override
public WebRTCMediaTrack[] getVideoTracks() {
return videoTracks;
}
@Override
public WebRTCMediaTrack[] getTracks() {
return allTracks;
}
@Override
public void close() {
if (isLocal) {
if (localAudioTrack != null) {
stream.removeTrack(localAudioTrack);
localAudioTrack.dispose();
localAudioTrack = null;
}
if (localVideoTrack != null) {
stream.removeTrack(localVideoTrack);
localVideoTrack.dispose();
localVideoTrack = null;
}
//
// I Have No idea why releasing of video/audio sources need to be here
// It is looks almost like "stream.dispose();" implementation, but
// before freeing stream we are releasing sources. But we already removed any track?
// Unlinking before track removing also produce crashes.
//
if (audioSource != null) {
audioSource.unlink();
audioSource = null;
}
if (videoSource != null) {
videoSource.unlink();
videoSource = null;
}
}
stream.dispose();
}
}