desc:摄像头视频预览
parent
65cc6c2d5f
commit
e0feb94d2a
Binary file not shown.
@ -1,21 +1,64 @@
|
||||
package com.yinuo.safetywatcher.ui.home
|
||||
|
||||
import android.view.TextureView
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
||||
import com.yinuo.safetywatcher.navi.ModelPath
|
||||
import com.yinuo.safetywatcher.navi.NavigationUtil
|
||||
|
||||
@OptIn(ExperimentalPermissionsApi::class)
|
||||
@Composable
|
||||
fun HomeView() {
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "Home")
|
||||
// 权限
|
||||
val permissionsState = rememberMultiplePermissionsState(
|
||||
permissions = listOf(
|
||||
android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
android.Manifest.permission.CAMERA,
|
||||
)
|
||||
)
|
||||
if (permissionsState.allPermissionsGranted) {
|
||||
val viewModel: HomeViewModel = viewModel()
|
||||
val context = LocalContext.current
|
||||
Row(modifier = Modifier.fillMaxSize()) {
|
||||
AndroidView(factory = {
|
||||
TextureView(it)
|
||||
}, modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.width(200.dp), update = {
|
||||
viewModel.setTextureView(it, context);
|
||||
})
|
||||
|
||||
Button(onClick = { NavigationUtil.to(ModelPath.Setting) }) {
|
||||
Text(text = "设置")
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.width(150.dp)
|
||||
.fillMaxHeight()
|
||||
.background(Color.Red)
|
||||
) {
|
||||
Button(onClick = { NavigationUtil.to(ModelPath.Setting) }) {
|
||||
Text(text = "设置")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LaunchedEffect(Unit) {
|
||||
permissionsState.launchMultiplePermissionRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
package com.yinuo.safetywatcher.ui.home
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.SurfaceTexture
|
||||
import android.util.Log
|
||||
import android.view.TextureView
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.yinuo.safetywatcher.utils.RxHelper
|
||||
import com.yinuo.safetywatcher.utils.SurfaceTextureListenerWrapper
|
||||
import io.reactivex.Single
|
||||
import org.easydarwin.push.MediaStream
|
||||
|
||||
class HomeViewModel : ViewModel() {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private var mediaStream: MediaStream? = null
|
||||
|
||||
private fun getMediaStream(context: Context, owner: LifecycleOwner): Single<MediaStream?>? {
|
||||
val single: Single<MediaStream?> =
|
||||
RxHelper.single(MediaStream.getBindedMediaStream(context, owner), mediaStream)
|
||||
return if (mediaStream == null) {
|
||||
single.doOnSuccess { ms -> mediaStream = ms }
|
||||
} else {
|
||||
single
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun setTextureView(it: TextureView, context: Context) {
|
||||
if (context is ComponentActivity) {
|
||||
val activity: ComponentActivity = context
|
||||
getMediaStream(context, activity)?.subscribe(
|
||||
{ ms ->
|
||||
if (it.isAvailable) {
|
||||
ms?.setSurfaceTexture(it.surfaceTexture)
|
||||
} else {
|
||||
it.surfaceTextureListener = object : SurfaceTextureListenerWrapper() {
|
||||
override fun onSurfaceTextureAvailable(
|
||||
surfaceTexture: SurfaceTexture,
|
||||
i: Int,
|
||||
i1: Int
|
||||
) {
|
||||
ms?.setSurfaceTexture(surfaceTexture)
|
||||
}
|
||||
|
||||
override fun onSurfaceTextureDestroyed(surfaceTexture: SurfaceTexture): Boolean {
|
||||
ms?.setSurfaceTexture(null)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Log.w("HomeViewModel", "创建服务出错!" + it.message)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.yinuo.safetywatcher.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.easydarwin.util.AbstractSubscriber;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
|
||||
/**
|
||||
* Created by apple on 2017/12/22.
|
||||
*/
|
||||
|
||||
public class RxHelper {
|
||||
static boolean IGNORE_ERROR = false;
|
||||
|
||||
public static <T> Single<T> single(@NonNull Publisher<T> t, @Nullable T defaultValueIfNotNull){
|
||||
if (defaultValueIfNotNull != null) return Single.just(defaultValueIfNotNull);
|
||||
final PublishSubject sub = PublishSubject.create();
|
||||
t.subscribe(new AbstractSubscriber<T>() {
|
||||
@Override
|
||||
public void onNext(T t) {
|
||||
super.onNext(t);
|
||||
sub.onNext(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
if (IGNORE_ERROR) {
|
||||
super.onError(t);
|
||||
sub.onComplete();
|
||||
}else {
|
||||
sub.onError(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
super.onComplete();
|
||||
sub.onComplete();
|
||||
}
|
||||
});
|
||||
return sub.firstOrError();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.yinuo.safetywatcher.utils;
|
||||
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.view.TextureView;
|
||||
|
||||
/**
|
||||
* Created by apple on 2017/9/11.
|
||||
*/
|
||||
|
||||
public abstract class SurfaceTextureListenerWrapper implements TextureView.SurfaceTextureListener{
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue