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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
dep: "brew update && brew install cocoapods xcodegen"
cmd: "./scripts/build_mac_demo.sh"
- os: windows-latest
cmd: ".\\scripts\\setup_windows.bat \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.43.34808\\bin\\Hostx64\\x64\\lib.exe\" && cd example\\winApp && msbuild winApp.vcxproj /t:Build /p:Configuration=Release /p:Platform=x64"
cmd: ".\\scripts\\setup_windows.bat \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.44.35207\\bin\\Hostx64\\x64\\lib.exe\" && cd example\\winApp && msbuild winApp.vcxproj /t:Build /p:Configuration=Release /p:Platform=x64"
- os: macos-latest
cmd: "./gradlew :example:webApp:jsBrowserDistribution"
- os: ubuntu-latest
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ Open the project (the repo root dir) in Android studio, and run the example.andr
### iOS

```bash
./scripts/setup_apple.sh
./scripts/setup_apple_demo.sh
# open example/iosApp/iosApp.xcworkspace in Xcode, and run it.
```

### macOS

```bash
./scripts/setup_apple.sh
./scripts/setup_apple_demo.sh
# open example/macApp/macApp.xcworkspace in Xcode, and run it.
```

Expand All @@ -91,6 +91,8 @@ Open the project (the repo root dir) in Android studio, and run the example.andr

### Linux

On Linux machine with GUI support.

```bash
./scripts/build_linux_demo.sh
./example/linuxApp/build/loopback <path to video file>
Expand All @@ -99,7 +101,7 @@ Open the project (the repo root dir) in Android studio, and run the example.andr
### JS

```bash
./gradlew :example:webApp:jsBrowserRun
./gradlew :example:webApp:jsBrowserDevelopmentRun
```

## Build WebRTC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
Expand Down Expand Up @@ -44,14 +45,7 @@

import static com.piasy.kmp.webrtc.AndroidPeerConnectionClientFactoryKt.createPeerConnectionClientFactory;
import static com.piasy.kmp.webrtc.AndroidPeerConnectionClientFactoryKt.initializeWebRTC;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_AUDIO_ONLY;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_IS_PUBLISHER;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_RECORD_CALL;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_VIDEO_BITRATE;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_VIDEO_CODEC;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_VIDEO_FPS;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_VIDEO_HEIGHT;
import static com.piasy.kmp.webrtc.android.HallActivity.EXTRA_VIDEO_WIDTH;
import static com.piasy.kmp.webrtc.android.HallActivity.*;

public class CallActivity extends AppCompatActivity implements PeerConnectionClientCallback, AudioMixer.MixerCallback {

Expand All @@ -61,6 +55,7 @@ public class CallActivity extends AppCompatActivity implements PeerConnectionCli
private static final boolean PAUSE_STREAMING = true;

private boolean isPublisher;
private boolean singlePc;
private boolean audioOnly;
private int videoWidth;
private int videoHeight;
Expand All @@ -87,6 +82,7 @@ public class CallActivity extends AppCompatActivity implements PeerConnectionCli
private EglBase eglBase;
private PeerConnectionClientFactory pcClientFactory;
private PeerConnectionClient pcClient;
private PeerConnectionClient recvPcClient;
private AudioMixer mixer;

private static int getSystemUiVisibility() {
Expand Down Expand Up @@ -117,6 +113,7 @@ protected void onCreate(Bundle savedInstanceState) {

isPublisher = intent.getBooleanExtra(EXTRA_IS_PUBLISHER, true);
recording = intent.getBooleanExtra(EXTRA_RECORD_CALL, false);
singlePc = intent.getBooleanExtra(EXTRA_SINGLE_PC, false);
audioOnly = intent.getBooleanExtra(EXTRA_AUDIO_ONLY, false);

videoWidth = intent.getIntExtra(EXTRA_VIDEO_WIDTH, 640);
Expand Down Expand Up @@ -300,11 +297,23 @@ public Unit invoke(Integer code, String msg) {

// 5. create PcClient
pcClient = pcClientFactory.createPeerConnectionClient(
"test", PeerConnectionClient.DIR_SEND_RECV, true, videoMaxBitrate, videoFps, this
"test",
singlePc ? PeerConnectionClient.DIR_SEND_RECV : PeerConnectionClient.DIR_SEND_ONLY,
true, videoMaxBitrate, videoFps, this
);
if (!singlePc) {
recvPcClient = pcClientFactory.createPeerConnectionClient(
"test-recv",
PeerConnectionClient.DIR_RECV_ONLY,
true, videoMaxBitrate, videoFps, this
);
}

// 6. create pc
pcClient.createPeerConnection(Collections.emptyList());
if (recvPcClient != null) {
recvPcClient.createPeerConnection(Collections.emptyList());
}

// 7. create offer
pcClient.createOffer();
Expand All @@ -313,14 +322,28 @@ public Unit invoke(Integer code, String msg) {
@Override
public void onLocalDescription(@NotNull String peerUid, @NotNull SessionDescription sdp) {
// 8. send offer to remote, get answer from remote, and set answer
SessionDescription answer = new SessionDescription(SessionDescription.ANSWER, sdp.getSdpDescription());
pcClient.setRemoteDescription(answer);
if (singlePc || TextUtils.equals(peerUid, "test-recv")) {
SessionDescription answer = new SessionDescription(SessionDescription.ANSWER, sdp.getSdpDescription());
pcClient.setRemoteDescription(answer);
} else if (TextUtils.equals(peerUid, "test")) {
SessionDescription offer = new SessionDescription(SessionDescription.OFFER, sdp.getSdpDescription());
recvPcClient.setRemoteDescription(offer);
recvPcClient.createAnswer();
}
}

@Override
public void onSetRemoteSdpResult(@NotNull String peerUid, boolean success) {
}

@Override
public void onIceCandidate(@NotNull String peerUid, @NotNull IceCandidate candidate) {
// 9. send ice candidate to remote, get ice candidate from remote, add ice candidate
pcClient.addIceCandidate(candidate);
if (singlePc || TextUtils.equals(peerUid, "test-recv")) {
pcClient.addIceCandidate(candidate);
} else if (TextUtils.equals(peerUid, "test")) {
recvPcClient.addIceCandidate(candidate);
}
}

@Override
Expand All @@ -329,7 +352,11 @@ public void onIceConnected(@NotNull String peerUid) {
@Override
public void run() {
// 10. on ice connected, add renderer for remote stream
pcClient.addRemoteTrackRenderer(remoteRenderer);
if (singlePc) {
pcClient.addRemoteTrackRenderer(remoteRenderer);
} else {
recvPcClient.addRemoteTrackRenderer(remoteRenderer);
}
}
});
}
Expand All @@ -343,6 +370,10 @@ private void disconnect() {
if (pcClientFactory != null) {
pcClientFactory.stopVideoCapture();
pcClient.close();
if (recvPcClient != null) {
recvPcClient.close();
recvPcClient = null;
}
pcClientFactory.destroyPeerConnectionFactory();
pcClientFactory = null;
pcClient = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
public class HallActivity extends Activity {

public static final String EXTRA_IS_PUBLISHER = "avconf.IS_PUBLISHER";
public static final String EXTRA_SINGLE_PC = "avconf.SINGLE_PC";
public static final String EXTRA_AUDIO_ONLY = "avconf.AUDIO_ONLY";
public static final String EXTRA_RECORD_CALL = "avconf.RECORD_CALL";
public static final String EXTRA_VIDEO_WIDTH = "avconf.VIDEO_WIDTH";
Expand All @@ -35,6 +36,7 @@ public class HallActivity extends Activity {
private String keyprefVideoBitrateValue;

private CheckBox mRecording;
private CheckBox mSinglePc;
private CheckBox mAudioOnly;
private CheckBox mPublisher;
private CheckBox mScreenShare;
Expand All @@ -59,6 +61,7 @@ protected void onCreate(Bundle savedInstanceState) {
tvVersion.setText("kmp-webrtc " + BuildConfig.VERSION_NAME);

mRecording = findViewById(R.id.recording);
mSinglePc = findViewById(R.id.single_pc);
mAudioOnly = findViewById(R.id.audio_only);
mPublisher = findViewById(R.id.publisher);
mScreenShare = findViewById(R.id.screen_share);
Expand All @@ -84,7 +87,8 @@ public void onRequestPermissionsResult(final int requestCode,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
Manifest.permission.BLUETOOTH,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_NETWORK_STATE
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.BLUETOOTH_CONNECT,
})
void checkPermission() {
mGotPermission = true;
Expand Down Expand Up @@ -145,6 +149,7 @@ private void startLoopback(Class activityClass) {
// Start AppRTCMobile activity.
Intent intent = new Intent(this, activityClass);
intent.putExtra(EXTRA_IS_PUBLISHER, mPublisher.isChecked());
intent.putExtra(EXTRA_SINGLE_PC, mSinglePc.isChecked());
intent.putExtra(EXTRA_AUDIO_ONLY, mAudioOnly.isChecked());
intent.putExtra(EXTRA_RECORD_CALL, mRecording.isChecked());
intent.putExtra(EXTRA_VIDEO_WIDTH, videoWidth);
Expand Down
12 changes: 10 additions & 2 deletions example/androidApp/src/main/res/layout/activity_hall.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,18 @@

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="130dp"
android:layout_height="wrap_content"
android:layout_marginLeft="160dp"
android:orientation="vertical"
>

<CheckBox
android:id="@+id/single_pc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="single pc"
/>

<CheckBox
android:id="@+id/audio_only"
android:layout_width="wrap_content"
Expand Down Expand Up @@ -71,7 +78,8 @@
android:id="@+id/tvVersion"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="130dp"
android:layout_marginBottom="20dp"
android:layout_gravity="bottom"
android:gravity="center"
tools:text="ver 1.0.0"
/>
Expand Down
1 change: 0 additions & 1 deletion example/iosApp/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ target 'iosApp' do
platform :ios, '14.0'
pod 'kmp_webrtc', :path => '../../kmp-webrtc/kmp_webrtc.podspec'
pod 'WebRTC', :path => '../../libs/apple/WebRTC.podspec'
pod 'kmp_xlog', '~> 1.3.4'
end
2 changes: 1 addition & 1 deletion example/iosApp/iosApp/ARDAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
// The main application class of the AppRTCMobile iOS app demonstrating
// interoperability between the Objective C implementation of PeerConnection
// and the appr.tc demo webapp.
@interface ARDAppDelegate : NSObject<UIApplicationDelegate>
@interface ARDAppDelegate : UIResponder<UIApplicationDelegate>
@end
29 changes: 15 additions & 14 deletions example/iosApp/iosApp/ARDAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,28 @@

#import "ARDAppDelegate.h"

#import "HallViewController.h"
#import "SceneDelegate.h"

@implementation ARDAppDelegate {
UIWindow *_window;
}
@implementation ARDAppDelegate

#pragma mark - UIApplicationDelegate methods

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 这里可以保留你的全局初始化代码
return YES;
}

_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[_window makeKeyAndVisible];
HallViewController *viewController = [[HallViewController alloc] init];
#pragma mark - UISceneSession lifecycle (iOS 13+)

UINavigationController *root =
[[UINavigationController alloc] initWithRootViewController:viewController];
root.navigationBar.translucent = NO;
_window.rootViewController = root;
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
// 当创建新场景时调用,返回一个场景配置对象
UISceneConfiguration *configuration = [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
configuration.delegateClass = [SceneDelegate class];
return configuration;
}

return YES;
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
// 当用户丢弃场景会话时调用
}

@end
1 change: 1 addition & 0 deletions example/iosApp/iosApp/CallViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface CallViewController : UIViewController

- (instancetype)initWithAudioOnly:(bool)audioOnly
singlePc:(bool)singlePc
isLandscape:(bool)isLandscape;

@end
Expand Down
Loading
Loading