mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
proof of concept to share Android Screen
note that this is very dirty and will break many things! basically video from camera was replaced by screen stream Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
1137d13d3a
commit
7e9fe266e1
@ -22,6 +22,7 @@
|
||||
|
||||
package com.nextcloud.talk.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
@ -82,6 +83,7 @@ class MagicCallActivity : BaseActivity() {
|
||||
RouterTransaction.with(CallController(intent.extras))
|
||||
.pushChangeHandler(HorizontalChangeHandler())
|
||||
.popChangeHandler(HorizontalChangeHandler())
|
||||
.tag("callController")
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -116,6 +118,13 @@ class MagicCallActivity : BaseActivity() {
|
||||
eventBus.post(ConfigurationChangeEvent())
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode != CallController.CAPTURE_PERMISSION_REQUEST_CODE) return
|
||||
val callController : CallController = router!!.getControllerWithTag("callController") as CallController
|
||||
callController.initScreenShare(resultCode, data);
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "MagicCallActivity"
|
||||
|
||||
|
@ -24,10 +24,15 @@ import android.Manifest;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.projection.MediaProjection;
|
||||
import android.media.projection.MediaProjectionManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@ -48,6 +53,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
@ -120,6 +126,7 @@ import org.webrtc.MediaStream;
|
||||
import org.webrtc.PeerConnection;
|
||||
import org.webrtc.PeerConnectionFactory;
|
||||
import org.webrtc.RendererCommon;
|
||||
import org.webrtc.ScreenCapturerAndroid;
|
||||
import org.webrtc.SessionDescription;
|
||||
import org.webrtc.SurfaceTextureHelper;
|
||||
import org.webrtc.SurfaceViewRenderer;
|
||||
@ -175,6 +182,7 @@ public class CallController extends BaseController {
|
||||
private static final String[] PERMISSIONS_MICROPHONE = {
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
};
|
||||
public static final int CAPTURE_PERMISSION_REQUEST_CODE = 1;
|
||||
|
||||
@BindView(R.id.callControlEnableSpeaker)
|
||||
SimpleDraweeView callControlEnableSpeaker;
|
||||
@ -194,6 +202,8 @@ public class CallController extends BaseController {
|
||||
SimpleDraweeView cameraControlButton;
|
||||
@BindView(R.id.call_control_switch_camera)
|
||||
SimpleDraweeView cameraSwitchButton;
|
||||
@BindView(R.id.callControlShareScreen)
|
||||
SimpleDraweeView callControlShareScreen;
|
||||
@BindView(R.id.callStateTextView)
|
||||
TextView callStateTextView;
|
||||
|
||||
@ -429,7 +439,9 @@ public class CallController extends BaseController {
|
||||
sdpConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
|
||||
|
||||
if (!isVoiceOnlyCall) {
|
||||
cameraInitialization();
|
||||
checkPermissions();
|
||||
// TODO change back to cameraInitialization (just changed this for androidScreensharing Proof of concept)
|
||||
// cameraInitialization();
|
||||
}
|
||||
|
||||
microphoneInitialization();
|
||||
@ -472,7 +484,6 @@ public class CallController extends BaseController {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void initViews() {
|
||||
participantDisplayItems = new HashMap<>();
|
||||
@ -573,16 +584,22 @@ public class CallController extends BaseController {
|
||||
|
||||
|
||||
private void checkPermissions() {
|
||||
if (isVoiceOnlyCall) {
|
||||
onMicrophoneClick();
|
||||
} else if (getActivity() != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestPermissions(PERMISSIONS_CALL, 100);
|
||||
} else {
|
||||
onRequestPermissionsResult(100, PERMISSIONS_CALL, new int[]{1, 1});
|
||||
}
|
||||
}
|
||||
// TODO revert (just changed this for androidScreensharing Proof of concept)
|
||||
// if (isVoiceOnlyCall) {
|
||||
// onMicrophoneClick();
|
||||
// } else if (getActivity() != null) {
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// requestPermissions(PERMISSIONS_CALL, 100);
|
||||
// } else {
|
||||
// onRequestPermissionsResult(100, PERMISSIONS_CALL, new int[]{1, 1});
|
||||
// }
|
||||
// }
|
||||
|
||||
MediaProjectionManager mediaProjectionManager =
|
||||
(MediaProjectionManager) getApplicationContext().getSystemService(
|
||||
Context.MEDIA_PROJECTION_SERVICE);
|
||||
getActivity().startActivityForResult(
|
||||
mediaProjectionManager.createScreenCaptureIntent(), CAPTURE_PERMISSION_REQUEST_CODE);
|
||||
}
|
||||
|
||||
private boolean isConnectionEstablished() {
|
||||
@ -704,6 +721,27 @@ public class CallController extends BaseController {
|
||||
localVideoTrack.addSink(pipVideoView);
|
||||
}
|
||||
|
||||
public void initScreenShare(int resultCode, Intent intent){
|
||||
videoCapturer = createScreenCapturer(resultCode, intent);
|
||||
|
||||
if (videoCapturer != null) {
|
||||
SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", rootEglBase.getEglBaseContext());
|
||||
videoSource = peerConnectionFactory.createVideoSource(true);
|
||||
videoCapturer.initialize(surfaceTextureHelper, getApplicationContext(), videoSource.getCapturerObserver());
|
||||
}
|
||||
|
||||
localVideoTrack = peerConnectionFactory.createVideoTrack("ARDAMSv0", videoSource);
|
||||
localMediaStream.addTrack(localVideoTrack);
|
||||
localVideoTrack.setEnabled(true);
|
||||
localVideoTrack.addSink(pipVideoView);
|
||||
|
||||
videoCapturer.startCapture(1000, 1000, 10);
|
||||
|
||||
if (!isConnectionEstablished()) {
|
||||
fetchSignalingSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void microphoneInitialization() {
|
||||
//create an AudioSource instance
|
||||
audioSource = peerConnectionFactory.createAudioSource(audioConstraints);
|
||||
@ -746,6 +784,20 @@ public class CallController extends BaseController {
|
||||
return null;
|
||||
}
|
||||
|
||||
private VideoCapturer createScreenCapturer(int resultCode, Intent intent) {
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
Log.d("","User didn't give permission to capture the screen.");
|
||||
return null;
|
||||
}
|
||||
return new ScreenCapturerAndroid(intent, new MediaProjection.Callback() {
|
||||
@Override
|
||||
public void onStop() {
|
||||
Log.d("","User revoked permission to capture the screen.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@OnLongClick(R.id.call_control_microphone)
|
||||
boolean onMicrophoneLongClick() {
|
||||
if (!audioOn) {
|
||||
@ -883,6 +935,11 @@ public class CallController extends BaseController {
|
||||
|
||||
}
|
||||
|
||||
@OnClick(R.id.callControlShareScreen)
|
||||
public void onCallControlShareScreenClick() {
|
||||
Toast.makeText(getApplicationContext(), "not yet implemented", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@OnClick({R.id.call_control_switch_camera})
|
||||
public void switchCamera() {
|
||||
CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer) videoCapturer;
|
||||
@ -1380,7 +1437,8 @@ public class CallController extends BaseController {
|
||||
|
||||
private void initiateCall() {
|
||||
if (!TextUtils.isEmpty(roomToken)) {
|
||||
checkPermissions();
|
||||
// TODO revert (just changed this for androidScreensharing Proof of concept)
|
||||
// checkPermissions();
|
||||
} else {
|
||||
handleFromNotification();
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M21.22,18.02l2,2L24,20.02v-2h-2.78zM21.99,16.02l0.01,-10c0,-1.11 -0.9,-2 -2,-2L7.22,4.02l5.23,5.23c0.18,-0.04 0.36,-0.07 0.55,-0.1L13,7.02l4,3.73 -1.58,1.47 5.54,5.54c0.61,-0.33 1.03,-0.99 1.03,-1.74zM2.39,1.73L1.11,3l1.54,1.54c-0.4,0.36 -0.65,0.89 -0.65,1.48v10c0,1.1 0.89,2 2,2L0,18.02v2h18.13l2.71,2.71 1.27,-1.27L2.39,1.73zM7,15.02c0.31,-1.48 0.92,-2.95 2.07,-4.06l1.59,1.59c-1.54,0.38 -2.7,1.18 -3.66,2.47z"/>
|
||||
</vector>
|
@ -152,6 +152,16 @@
|
||||
app:placeholderImage="@drawable/ic_comment_white"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/callControlShareScreen"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:backgroundImage="@color/call_buttons_background"
|
||||
app:placeholderImage="@drawable/ic_baseline_stop_screen_share_24"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/callControlEnableSpeaker"
|
||||
android:layout_width="60dp"
|
||||
|
Loading…
Reference in New Issue
Block a user