Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

--------------------------------------------
[0.12.3] - 2024-11-29

* [iOS/Android/macOS] feat: Expose AV Processing and Sink native APIs.

[0.12.2+1] - 2024-11-26

* [iOS/Android] Added video effects support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ private FrameCryptorAlgorithm frameCryptorAlgorithmFromInt(int algorithm) {
switch (algorithm) {
case 0:
return FrameCryptorAlgorithm.AES_GCM;
case 1:
return FrameCryptorAlgorithm.AES_CBC;
default:
return FrameCryptorAlgorithm.AES_GCM;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import io.getstream.webrtc.flutter.audio.AudioProcessingController;
import io.getstream.webrtc.flutter.audio.AudioSwitchManager;
import io.getstream.webrtc.flutter.utils.AnyThreadSink;
import io.getstream.webrtc.flutter.utils.ConstraintsMap;

import org.webrtc.ExternalAudioProcessingFactory;
import org.webrtc.MediaStreamTrack;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
Expand All @@ -41,6 +45,25 @@ public class FlutterWebRTCPlugin implements FlutterPlugin, ActivityAware, EventC
public EventChannel.EventSink eventSink;

public FlutterWebRTCPlugin() {
sharedSingleton = this;
}

public static FlutterWebRTCPlugin sharedSingleton;

public AudioProcessingController getAudioProcessingController() {
return methodCallHandler.audioProcessingController;
}

public MediaStreamTrack getTrackForId(String trackId, String peerConnectionId) {
return methodCallHandler.getTrackForId(trackId, peerConnectionId);
}

public LocalTrack getLocalTrack(String trackId) {
return methodCallHandler.getLocalTrack(trackId);
}

public MediaStreamTrack getRemoteTrack(String trackId) {
return methodCallHandler.getRemoteTrack(trackId);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import io.getstream.webrtc.flutter.audio.AudioSwitchManager;
import io.getstream.webrtc.flutter.audio.AudioUtils;
import io.getstream.webrtc.flutter.audio.LocalAudioTrack;
import io.getstream.webrtc.flutter.record.AudioChannel;
import io.getstream.webrtc.flutter.record.AudioSamplesInterceptor;
import io.getstream.webrtc.flutter.record.MediaRecorderImpl;
Expand All @@ -56,6 +57,7 @@
import io.getstream.webrtc.flutter.videoEffects.VideoFrameProcessor;
import io.getstream.webrtc.flutter.videoEffects.VideoEffectProcessor;
import io.getstream.webrtc.flutter.videoEffects.ProcessorProvider;
import io.getstream.webrtc.flutter.video.LocalVideoTrack;

import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
Expand Down Expand Up @@ -383,7 +385,9 @@ private ConstraintsMap getUserAudio(ConstraintsMap constraints, MediaStream stre

if (deviceId != null) {
try {
setPreferredInputDevice(deviceId);
if (VERSION.SDK_INT >= VERSION_CODES.M) {
setPreferredInputDevice(deviceId);
}
} catch (Exception e) {
Log.e(TAG, "setPreferredInputDevice failed", e);
}
Expand All @@ -392,7 +396,7 @@ private ConstraintsMap getUserAudio(ConstraintsMap constraints, MediaStream stre
AudioTrack track = pcFactory.createAudioTrack(trackId, audioSource);
stream.addTrack(track);

stateProvider.putLocalTrack(track.id(), track);
stateProvider.putLocalTrack(track.id(), new LocalAudioTrack(track));

ConstraintsMap trackParams = new ConstraintsMap();
trackParams.putBoolean("enabled", track.enabled());
Expand All @@ -403,7 +407,9 @@ private ConstraintsMap getUserAudio(ConstraintsMap constraints, MediaStream stre
trackParams.putBoolean("remote", false);

if (deviceId == null) {
deviceId = "" + getPreferredInputDevice(preferredInput);
if (VERSION.SDK_INT >= VERSION_CODES.M) {
deviceId = "" + getPreferredInputDevice(preferredInput);
}
}

ConstraintsMap settings = new ConstraintsMap();
Expand Down Expand Up @@ -522,7 +528,7 @@ protected void onReceiveResult(int requestCode, Bundle resultData) {

private void getDisplayMedia(final Result result, final MediaStream mediaStream, final Intent mediaProjectionData) {
/* Create ScreenCapture */
MediaStreamTrack[] tracks = new MediaStreamTrack[1];
VideoTrack displayTrack = null;
VideoCapturer videoCapturer = null;
videoCapturer =
new OrientationAwareScreenCapturer(
Expand Down Expand Up @@ -570,41 +576,31 @@ public void onStop() {
String trackId = stateProvider.getNextTrackUUID();
mVideoCapturers.put(trackId, info);

tracks[0] = pcFactory.createVideoTrack(trackId, videoSource);
displayTrack = pcFactory.createVideoTrack(trackId, videoSource);

ConstraintsArray audioTracks = new ConstraintsArray();
ConstraintsArray videoTracks = new ConstraintsArray();
ConstraintsMap successResult = new ConstraintsMap();

for (MediaStreamTrack track : tracks) {
if (track == null) {
continue;
}
if (displayTrack != null) {
String id = displayTrack.id();

String id = track.id();
LocalVideoTrack displayLocalVideoTrack = new LocalVideoTrack(displayTrack);
videoSource.setVideoProcessor(displayLocalVideoTrack);

if (track instanceof AudioTrack) {
mediaStream.addTrack((AudioTrack) track);
} else {
mediaStream.addTrack((VideoTrack) track);
}
stateProvider.putLocalTrack(id, track);
stateProvider.putLocalTrack(id, displayLocalVideoTrack);

ConstraintsMap track_ = new ConstraintsMap();
String kind = track.kind();
String kind = displayTrack.kind();

track_.putBoolean("enabled", track.enabled());
track_.putBoolean("enabled", displayTrack.enabled());
track_.putString("id", id);
track_.putString("kind", kind);
track_.putString("label", kind);
track_.putString("readyState", track.state().toString());
track_.putString("readyState", displayTrack.state().toString());
track_.putBoolean("remote", false);

if (track instanceof AudioTrack) {
audioTracks.pushMap(track_);
} else {
videoTracks.pushMap(track_);
}
videoTracks.pushMap(track_);
}

String streamId = mediaStream.getId();
Expand Down Expand Up @@ -758,6 +754,13 @@ private ConstraintsMap getUserVideo(ConstraintsMap constraints, MediaStream medi
deviceId = result.first;
VideoCapturer videoCapturer = result.second;

if (facingMode == null && cameraEnumerator.isFrontFacing(deviceId)) {
facingMode = "user";
} else if (facingMode == null && cameraEnumerator.isBackFacing(deviceId)) {
facingMode = "environment";
}
// else, leave facingMode as it was

PeerConnectionFactory pcFactory = stateProvider.getPeerConnectionFactory();
VideoSource videoSource = pcFactory.createVideoSource(false);
String threadName = Thread.currentThread().getName() + "_texture_camera_thread";
Expand Down Expand Up @@ -824,7 +827,10 @@ private ConstraintsMap getUserVideo(ConstraintsMap constraints, MediaStream medi
VideoTrack track = pcFactory.createVideoTrack(trackId, videoSource);
mediaStream.addTrack(track);

stateProvider.putLocalTrack(track.id(), track);
LocalVideoTrack localVideoTrack = new LocalVideoTrack(track);
videoSource.setVideoProcessor(localVideoTrack);

stateProvider.putLocalTrack(track.id(),localVideoTrack);

ConstraintsMap trackParams = new ConstraintsMap();

Expand Down
31 changes: 31 additions & 0 deletions android/src/main/java/io/getstream/webrtc/flutter/LocalTrack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.getstream.webrtc.flutter;

import org.webrtc.MediaStreamTrack;

public class LocalTrack {
public LocalTrack(MediaStreamTrack track) {
this.track = track;
}

public MediaStreamTrack track;

public void dispose() {
track.dispose();
}

public boolean enabled() {
return track.enabled();
}

public void setEnabled(boolean enabled) {
track.setEnabled(enabled);
}

public String id() {
return track.id();
}

public String kind() {
return track.kind();
}
}
Loading