当前位置: 首页 > news >正文

旅游营销型网站qq空间转wordpress

旅游营销型网站,qq空间转wordpress,学电商需要多少钱,电子商务网站建设与维护实训题库在“Android笔记(八):基于CameraX库结合Compose和传统视图组件PreviewView实现照相机画面预览和照相功能”,文中介绍了拍照功能的实现,在本文中将介绍结合JetPack Compose和CameraX实现视频的录制。 新建一个项目 在项…

在“Android笔记(八):基于CameraX库结合Compose和传统视图组件PreviewView实现照相机画面预览和照相功能”,文中介绍了拍照功能的实现,在本文中将介绍结合JetPack Compose和CameraX实现视频的录制。
新建一个项目
在这里插入图片描述
在项目中做如下处理:

一、增视频录制的相关依赖库

在项目的模块对应的build.gradle.kt中增加如下的依赖库:
增加CameraX相关库

  val camerax_version = "1.3.0-alpha04"implementation("androidx.camera:camera-core:$camerax_version")implementation("androidx.camera:camera-camera2:${camerax_version}")implementation("androidx.camera:camera-lifecycle:${camerax_version}")implementation("androidx.camera:camera-video:${camerax_version}")implementation("androidx.camera:camera-view:${camerax_version}" )implementation("androidx.camera:camera-extensions:${camerax_version}")

增加Material3中扩展的图标库

  val icon_extended_version = "1.5.4"implementation("androidx.compose.material:material-icons-extended:$icon_extended_version")

注意:因为在前面展示的Android移动应用中使用的图标可选有限,因此增加“androidx.compose.material:material-icons-extended”图标扩展库,丰富图标的选择。

二、在AndroidManifest.xml权限设置使用照相机

  <uses-feature android:name="android.hardware.camera"  android:required="false" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.RECORD_AUDIO" />

三、CameraX视频捕获架构

视频录制需要做两个方面的处理,需要录制视频流和同时录制音频流。然后对音频流和视频流进行压缩处理,最终写入到磁盘保存起来。在图1展示的是这样工作的示意图。
在这里插入图片描述
图1
LifecycleCameraController
CameraX提供了LifecycleCameraController。LifecycleCameraController提供了CameraX的大部分的特性,它是一个高级的控制器类提供了CameraX的核心特性,用于处理照相机的初始化、创建和配置用例(这里的用例提供了将用例参数映射到相机的可用参数的功能,具体这些用例是指:拍照用例:CameraController.IMAGE_CAPTURE、 图像分析用例:CameraController.IMAGE_ANALYSIS、视频录制用例:CameraController.VIDEO_CAPTURE,…),并将它们绑定到一个生命周期拥有者对象。LifecycleCamera监听设备的Motion Sensor(运动感应器),设置目标的旋转参数。

val cameraController: LifecycleCameraController
= LifecycleCameraController(applicationContext).apply {
setEnabledUseCases(CameraController.VIDEO_CAPTURE) //设置用例
}

CameraSelector
CameraSelector用于选择摄像头,具体选择包括:

使用 CameraSelector.DEFAULT_FRONT_CAMERA 请求默认的前置摄像头。
使用 CameraSelector.DEFAULT_BACK_CAMERA 请求默认的后置摄像头。
使用CameraSelector.Builder.addCameraFilter() 按 CameraCharacteristics 过滤可用设备列表。

Recording
Recording是实际上执行录制视频的对象,在活动录制视频时,提供暂停、恢复或停止录制的控件。如果在录制的过程中发生错误,则会初始化一个VideoRecordEvent.Finalized状态,所有的控制将进入空操作。
//创建Recording对象并启动视频录制
val recording = cameraController.startRecording(…)
在这里:startRecording根据录制得到的视频存储处理方式不同有三种形式:
(1)写入到文件

public Recording startRecording(
@NonNull FileOutputOptions outputOptions, //写入到文件的输出参数
@NonNull AudioConfig audioConfig, //音频的配置
@NonNull Executor executor,//将在其上运行事件侦听器的线程池
@NonNull Consumer listener)//处理视频录制的事件监听器

(2)根据文件描述写入到文件

public Recording startRecording(
@NonNull FileDescriptorOutputOptions outputOptions,//写入到文件描述的输出参数
@NonNull AudioConfig audioConfig,//音频的配置
@NonNull Executor executor,//将在其上运行事件侦听器的线程池
@NonNull Consumer listener)//处理视频录制的事件监听器

(3)写入到媒体库

public Recording startRecording(
@NonNull MediaStoreOutputOptions outputOptions,//写入到媒体库的输出参数
@NonNull AudioConfig audioConfig,//音频的配置
@NonNull Executor executor,//将在其上运行事件侦听器的线程池
@NonNull Consumer listener)//处理视频录制的事件监听器

四、结合Compose和CameraX实现视频的录制实例

1.在主活动中设置权限处理

class MainActivity : ComponentActivity() {companion object{//定义权限数组val CAMERAX_PERMISSIONS = arrayOf(android.Manifest.permission.CAMERA,			//请求相机android.Manifest.permission.RECORD_AUDIO)	//请求录制音频}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//检查权限,若无就请求权限handlePermissions()setContent {val cameraController: LifecycleCameraController = remember {LifecycleCameraController(applicationContext).apply {setEnabledUseCases(CameraController.VIDEO_CAPTURE)}}VideoCaptureAppTheme {MainScreen(cameraController)}}}/*** 检查权限* @return Boolean*/private fun hasRequiredPermissions():Boolean = CAMERAX_PERMISSIONS.all{ContextCompat.checkSelfPermission(applicationContext,it) == PackageManager.PERMISSION_GRANTED}/*** Handle permissions* 处理权限的操作*/private fun handlePermissions(){if(!hasRequiredPermissions()){//请求权限ActivityCompat.requestPermissions(this, CAMERAX_PERMISSIONS,0)}}
}

运行结果如图2所示:
在这里插入图片描述
图2

2. 定义视频预览界面定义

利用view视图组件PreviewView来定义视频预览的界面,同时处理将LifecycleCameraController对象与当前的生命周期对象进行绑定。由当前生命周期拥有者LocalLifecycleOwner.current的生命周期lifecycle的状态将决定摄像机何时打开、启动、停止和关闭。

@Composable
fun VideoPreview(cameraController:LifecycleCameraController,modifier: Modifier = Modifier){val lifecycleOwner = LocalLifecycleOwner.currentAndroidView(factory={context: Context ->//预览视图PreviewView(context).apply{this.controller = cameraControllercameraController.bindToLifecycle(lifecycleOwner)}},modifier = modifier)
}

3. 定义主界面设置摄像头前后镜头切换

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(cameraController: LifecycleCameraController){//设置前后摄像头的图标状态var cameraIcon by remember{mutableStateOf(Icons.Default.VideoCameraBack)}Scaffold {Box(modifier = Modifier.fillMaxSize().padding(it)) {//视频预览的界面VideoPreview(cameraController = cameraController, modifier = Modifier.fillMaxSize())//左上角的摄像头前后镜图标IconButton(onClick = {//照相机前后摄像头的切换if (cameraController.cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) {//设置后镜头cameraController.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERAcameraIcon = Icons.Default.VideoCameraBack} else {//设置前镜头cameraController.cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERAcameraIcon=Icons.Default.VideoCameraFront}}, modifier = Modifier.offset(16.dp, 16.dp)) {Icon(imageVector = cameraIcon,tint = Color.Green,contentDescription = "摄像头")}}}
}

运行结果如图3所示:
在这里插入图片描述
图3

4.在主活动中增加录制视频的处理

(1)将录制的视频保存到文件中

下列代码将录制视频采用下列录制的方式

public Recording startRecording(
@NonNull FileOutputOptions outputOptions, //写入到文件的输出参数
@NonNull AudioConfig audioConfig, //音频的配置
@NonNull Executor executor,//将在其上运行事件侦听器的线程池
@NonNull Consumer listener)//处理视频录制的事件监听器

这样的视频文件就会保存到当前应用包下的文件目录中,具体代码如下所示:

class MainActivity : ComponentActivity() {private var recording: Recording? = nullcompanion object{val CAMERAX_PERMISSIONS = arrayOf(android.Manifest.permission.CAMERA,//请求相机android.Manifest.permission.RECORD_AUDIO)//请求录制音频}@SuppressLint("UnsafeOptInUsageError")override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//检查权限,若无就请求权限handlePermissions()setContent {val cameraController: LifecycleCameraController = remember {LifecycleCameraController(applicationContext).apply {setEnabledUseCases(CameraController.VIDEO_CAPTURE)}}VideoCaptureAppTheme {MainScreen(cameraController,this::recordVideo)}}}/*** 检查权限* @return Boolean*/private fun hasRequiredPermissions():Boolean = CAMERAX_PERMISSIONS.all{ContextCompat.checkSelfPermission(applicationContext,it) == PackageManager.PERMISSION_GRANTED}/*** Request permissions* 处理权限的操作*/private fun handlePermissions(){if(!hasRequiredPermissions()){//请求权限ActivityCompat.requestPermissions(this, CAMERAX_PERMISSIONS,0)}}/*** 录制视频* @param cmaeraController LifecycleCameraController*/@SuppressLint("MissingPermission", "UnsafeOptInUsageError")private fun recordVideo(cameraController:LifecycleCameraController){if(recording!=null){//停止录制视频recording?.stop()recording = nullreturn}if(!hasRequiredPermissions())//没有访问权限returnval outputFile = File(filesDir,"video.mp4")//执行视频录制recording = cameraController.startRecording(//输出文件配置FileOutputOptions.Builder(outputFile).build(),//启动语音AudioConfig.create(true),//在当前应用的上下文中创建事件监听器依附运行的线程池ContextCompat.getMainExecutor(applicationContext)){event:VideoRecordEvent->//监听器处理器when(event){is VideoRecordEvent.Finalize->{if(event.hasError()){recording?.close()recording = nullToast.makeText(applicationContext,"录制视频失败",Toast.LENGTH_LONG).show()}else{Toast.makeText(applicationContext,"录制视频成功",Toast.LENGTH_LONG).show()}}}}}
}@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(cameraController: LifecycleCameraController,onRecordAction:(cameraController:LifecycleCameraController)->Unit){//设置前后摄像头的图标状态var cameraIcon by remember{mutableStateOf(Icons.Default.VideoCameraBack)}var selected by remember{mutableStateOf(false)}Scaffold(bottomBar = {BottomAppBar {NavigationBarItem(selected = selected,onClick = {onRecordAction(cameraController)},icon = {Icon(imageVector = Icons.Default.Videocam,contentDescription = "视频录制")})}}) {Box(modifier = Modifier.fillMaxSize().padding(it)) {VideoPreview(cameraController = cameraController, modifier = Modifier.fillMaxSize())IconButton(onClick = {//照相机前后摄像头的切换if (cameraController.cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) {cameraController.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERAcameraIcon = Icons.Default.VideoCameraBack} else {cameraController.cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERAcameraIcon=Icons.Default.VideoCameraFront}}, modifier = Modifier.offset(16.dp, 16.dp)) {Icon(imageVector = cameraIcon,tint = Color.Green,contentDescription = "摄像头")}}}
}

运行结果如图4所示:
在这里插入图片描述
图4
启动Device Explorer设备浏览器,在:data->data->对应应用的包名->files“目录下可以发现已经录制成功的视频文件video.mp4。
在这里插入图片描述
图5

(2)保存视频到媒体库

上述的代码需要检索并浏览录制的视频非常困难,并不是一个很好的方法。比较好的处理方式,是将录制的视频直接保存在媒体库中。通过将时间戳作为视频文件名,根据时间便可以非常方便的在移动终端的媒体库中检索和浏览录制的视频。则就需要在录制视频中采用如下的方式:

public Recording startRecording(
@NonNull MediaStoreOutputOptions outputOptions,//写入到媒体库的输出参数
@NonNull AudioConfig audioConfig,//音频的配置
@NonNull Executor executor,//将在其上运行事件侦听器的线程池
@NonNull Consumer listener)//处理视频录制的事件监听器

将上述的MainActivity中关于视频录制的私有方法recordVideo重新定义,具体代码如下:

class MainActivity : ComponentActivity() {private var recording: Recording? = nullcompanion object{val CAMERAX_PERMISSIONS = arrayOf(android.Manifest.permission.CAMERA,//请求相机android.Manifest.permission.RECORD_AUDIO)//请求录制音频}@SuppressLint("UnsafeOptInUsageError")override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//检查权限,若无就请求权限handlePermissions()setContent {val cameraController: LifecycleCameraController = remember {LifecycleCameraController(applicationContext).apply {setEnabledUseCases(CameraController.VIDEO_CAPTURE)}}VideoCaptureAppTheme {MainScreen(cameraController,this::recordVideo)}}}/*** 检查权限* @return Boolean*/private fun hasRequiredPermissions():Boolean = CAMERAX_PERMISSIONS.all{ContextCompat.checkSelfPermission(applicationContext,it) == PackageManager.PERMISSION_GRANTED}/*** Request permissions* 处理权限的操作*/private fun handlePermissions(){if(!hasRequiredPermissions()){//请求权限ActivityCompat.requestPermissions(this, CAMERAX_PERMISSIONS,0)}}/*** 录制视频到文件* @param cmaeraController LifecycleCameraController*/@SuppressLint("MissingPermission", "UnsafeOptInUsageError")private fun recordVideo(cameraController:LifecycleCameraController){if(recording!=null){//停止录制视频recording?.stop()recording = nullreturn}if(!hasRequiredPermissions())//没有访问权限return//定义包含时间戳的视频文件名val name = SimpleDateFormat("yyyy-MM-dd hh:mm:ss",Locale.CHINA).format(System.currentTimeMillis())//定义关于一条视频记录的相关配置val contentValue = ContentValues().apply{put(MediaStore.MediaColumns.DISPLAY_NAME,name)put(MediaStore.MediaColumns.MIME_TYPE,"video/mp4")if(Build.VERSION.SDK_INT>Build.VERSION_CODES.P){put(MediaStore.Video.Media.RELATIVE_PATH,"Movies/CameraX-Video")}}//配置输出到媒体库的输出参数val mediaStoreOutputOptions = MediaStoreOutputOptions.Builder(contentResolver,MediaStore.Video.Media.EXTERNAL_CONTENT_URI).setContentValues(contentValue).build()//执行视频录制recording = cameraController.startRecording(//输出到媒体库的配置mediaStoreOutputOptions,//启动语音AudioConfig.create(true),//在当前应用的上下文中创建事件监听器依附运行的线程池ContextCompat.getMainExecutor(applicationContext)){event:VideoRecordEvent->//监听器处理器when(event){is VideoRecordEvent.Finalize->{if(event.hasError()){recording?.close()recording = nullToast.makeText(applicationContext,"录制视频失败",Toast.LENGTH_LONG).show()}else{Toast.makeText(applicationContext,"录制视频成功",Toast.LENGTH_LONG).show()}}}}}
}

运行录制视频后,在手机模拟器的图片库中可以发现刚刚录制的视频,运行结果如图6所示。
在这里插入图片描述
图6

五、设置WebCam为模拟器的摄像头

当然,模拟器的前后镜头可以自行设置webCam0,如图6所示。
在这里插入图片描述
图7
对于Camera Front和Camera Back可以任选其一设置为Webcam0,不能二者同时进行设置为WebCam0。通过这样的设置,可以在模拟器中启动WebCam,录制实时的视频。运行效果类似图8所示:
在这里插入图片描述
图8

六、参考文献

1.CameraX视频捕获架构

https://developer.android.google.cn/training/camerax/video-capture?hl=zh-cn

http://www.yayakq.cn/news/547327/

相关文章:

  • 网站运营前期中期后期企业网站的建设过程
  • 江门网站开发北京网页设计和网页制作
  • 使用国外空间的网站刷关键词要刷大词吗
  • 发新闻稿做新闻源对网站有啥帮助公司logo怎么注册
  • 关于网站建设的外文文献ui设计师是做网站吗
  • 手机网站建设开发报价衡水网站seo
  • 阐述建站流程wordpress 漂亮按钮
  • 网站建设平台官网页面模板怎么设置
  • 站内优化主要从哪些方面进行怎么办?
  • 网站建设应注意哪些问题深圳市做网站知名公司有哪些
  • 类似58同城的网站怎么做来年做那个网站能致富
  • 怎样选深圳网站建设可以找酒店案例的网站
  • 网络建设网站郑州房产网官网
  • 做网站的技术哪个简单珠海横琴建设局网站
  • 河北网站备案管理系统唐卡装饰集团 一站式超级体验店
  • 网站轮播图怎么做1元网站建设精品网站制作
  • 网络营销网站推广方法网站如何做sem推广
  • 本地怎样上传自己做的网站网络科技公司介绍
  • 门户网站模板免费下载企业培训体系
  • 电商网站那些功能用到静态化功能建网站要自己买服务器吗
  • cp网站开发是什么贵阳网站建设哪里好
  • 视频网站移动端投资理财网站模板
  • 网站建设什么打王思聪wordpress如何生成rss
  • 运城做网站的公司家具 东莞网站建设
  • 做网站用母版页不好么wordpress 标签云插件下载
  • 瑞安商城网站建设怎么在网站做谷歌广告
  • html论坛源码seo网站关键词排名提升
  • 做静态网站需要什么网站建设合同性质
  • 网上书店网站建设实训报告总结许昌做网站优化
  • 顺德网站制作案例价位有免费做网站的吗