mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-04-17 21:38:29 +00:00
Show video preview in in-call conversation screen
This commit is contained in:
parent
7fe554be3c
commit
1c4f73a9b8
6 changed files with 116 additions and 0 deletions
|
|
@ -34,6 +34,7 @@ Group changes to describe their impact on the project, as follows:
|
|||
- one to let edit native contacts Linphone copy in-app instead of opening native addressbook third party app
|
||||
- Added a vu meter for recording & playback volumes (must be enabled in developer settings)
|
||||
- Added support for HDMI audio devices
|
||||
- Added video preview during in-call conversation
|
||||
|
||||
### Changed
|
||||
- No longer follow TelecomManager audio endpoint during calls, using our own routing policy
|
||||
|
|
|
|||
|
|
@ -19,12 +19,20 @@
|
|||
*/
|
||||
package org.linphone.ui.call.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.doOnLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.call.view.RoundCornersTextureView
|
||||
import org.linphone.ui.call.viewmodel.CurrentCallViewModel
|
||||
import org.linphone.ui.fileviewer.FileViewerActivity
|
||||
import org.linphone.ui.fileviewer.MediaViewerActivity
|
||||
import org.linphone.ui.main.chat.fragment.ConversationFragment
|
||||
|
|
@ -34,9 +42,48 @@ class ConversationFragment : ConversationFragment() {
|
|||
private const val TAG = "[In-call Conversation Fragment]"
|
||||
}
|
||||
|
||||
private lateinit var callViewModel: CurrentCallViewModel
|
||||
|
||||
private lateinit var localPreviewVideoSurface: RoundCornersTextureView
|
||||
|
||||
private var videoPreviewX: Float = 0f
|
||||
private var videoPreviewY: Float = 0f
|
||||
|
||||
// For moving video preview purposes
|
||||
private val videoPreviewTouchListener = View.OnTouchListener { view, event ->
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
videoPreviewX = view.x - event.rawX
|
||||
videoPreviewY = view.y - event.rawY
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
videoPreviewX = view.x
|
||||
videoPreviewY = view.y
|
||||
true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.animate()
|
||||
.x(event.rawX + videoPreviewX)
|
||||
.y(event.rawY + videoPreviewY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
view.performClick()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
callViewModel = requireActivity().run {
|
||||
ViewModelProvider(this)[CurrentCallViewModel::class.java]
|
||||
}
|
||||
|
||||
Log.i("$TAG Creating an in-call ConversationFragment")
|
||||
sendMessageViewModel.isCallConversation.value = true
|
||||
viewModel.isCallConversation.value = true
|
||||
|
|
@ -70,5 +117,50 @@ class ConversationFragment : ConversationFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
val layout = layoutInflater.inflate(R.layout.call_video_local_preview_surface, binding.constraintLayout, false)
|
||||
binding.constraintLayout.addView(layout)
|
||||
localPreviewVideoSurface = layout.findViewById<RoundCornersTextureView>(R.id.local_preview_video_surface)
|
||||
|
||||
callViewModel.isSendingVideo.observe(viewLifecycleOwner) { sending ->
|
||||
coreContext.postOnCoreThread { core ->
|
||||
core.nativePreviewWindowId = if (sending) {
|
||||
Log.i("$TAG We are sending video, setting capture preview surface")
|
||||
localPreviewVideoSurface
|
||||
} else {
|
||||
Log.i("$TAG We are not sending video, clearing capture preview surface")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
(binding.root as? ViewGroup)?.doOnLayout {
|
||||
setupVideoPreview(localPreviewVideoSurface)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
cleanVideoPreview(localPreviewVideoSurface)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) {
|
||||
if (requireActivity().isInPictureInPictureMode) {
|
||||
Log.i("$TAG Activity is in PiP mode, do not move video preview")
|
||||
return
|
||||
}
|
||||
|
||||
localPreviewVideoSurface.setOnTouchListener(videoPreviewTouchListener)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun cleanVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) {
|
||||
localPreviewVideoSurface.setOnTouchListener(null)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:alignTopRight="true"
|
||||
app:displayMode="black_bars"
|
||||
roundCornersRadius="@dimen/call_round_corners_texture_view_radius"
|
||||
|
|
|
|||
20
app/src/main/res/layout/call_video_local_preview_surface.xml
Normal file
20
app/src/main/res/layout/call_video_local_preview_surface.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<org.linphone.ui.call.view.RoundCornersTextureView
|
||||
android:id="@+id/local_preview_video_surface"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
app:alignTopRight="true"
|
||||
app:displayMode="black_bars"
|
||||
roundCornersRadius="@dimen/call_round_corners_texture_view_radius"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHeight_max="@dimen/call_video_preview_max_size"
|
||||
app:layout_constraintWidth_max="@dimen/call_video_preview_max_size" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -98,6 +98,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:alignTopRight="true"
|
||||
app:displayMode="black_bars"
|
||||
roundCornersRadius="@dimen/call_round_corners_texture_view_radius"
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraint_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/color_background_contrast_in_dark_mode">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue