多媒体包括图片、动画、音频、视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件。当然随着硬件集成度越来越高,也有些基础功能内置到硬件中解码,以此减少软件解码过程中的CPU耗时操作,这种方式称为硬件加速。由于多媒体的播放渲染(输出)是由系统主动向用户发出的,通常不需要向用户申请权限。系统将数据直接发给应用程序,进而在应用程序内编程实现相关数据的解码播放渲染(输出)操作。故文章重点介绍在多媒体采集(输入)过程中可能用到的硬件及相关使用流程。
摄像头作为移动手机设备的重要硬件之一,从最初的单一摄像头,到最新的浴霸式四孔摄像头,不管是数量,还是焦距性能上,在不同设备上都有不同的区别。与传感器系列硬件交互一文相似的是,这些繁杂的类型,都由系统适配完成。而应用程序只需要使用系统提供的相关类即可。
对于摄像头硬件的使用,在Android5.0即API级别21以下的系统版本中,可以使用android.hardware.Camera摄像头类的相关方法来获取摄像头数据,以用来实时预览摄像头采集的数据、拍照保存某一时刻的数据、或录制视频保存一段时刻内的数据,但是从Android5.0开始,上述类由于过于臃肿而废弃,进而使用android.hardware.camra2. 包下的相关类开发更定制化的应用。
对于使用摄像头硬件的应用程序,都需要声明权限为Manifest.permissions.CAMERA="android.permission.CAMERA"。
同样也可以在应用程序清单文件中声明需要摄像头硬件的设备支持,也可以增加标签信息<uses-feature android:name="android.hardware.camera"/>。
另外,如果在使用摄像头拍照时,需要在照片中保存位置信息,应用程序需要申请位置权限;而想将照片存储到外部存储设备,还需要应用程序申请读写外部存储的相关权限;如果是使用摄像头录制有声视频,应用程序还需要申请麦克风权限。
在使用前首先检测摄像头硬件,在能获取到Context上下文环境对象的位置,调用上下文环境对象的getPackageManager()方法获取android.content.pm.PackageManager包管理类的实例化对象,进而通过该对象的hasSystemFeature(String featureName)方法,使参数 featureName 值为PackageManager.FEATURE_CAMERA 代表摄像头功能,来判断当前系统是否有摄像头硬件的支持。
对于有摄像头硬件支持的设备,可以使用Camera.getNumberOfCameras()静态方法获取当前设备的所有可用摄像头数量,而每个摄像头硬件都对应一个int类型的 cameraId 属性编号,其值大于等于0,且小于静态方法获取可用摄像头数量,在下面获取摄像头信息和打开指定摄像头时均是根据 cameraId 属性值确定的。
对于每一个具有 cameraId 属性值的摄像头,都可以调用Camera.open(int cameraId)方法获取到对应的Camera摄像头类的实例化对象。参数 cameraId 即上文提到的摄像头硬件编号,该参数默认值为0;如果编号参数对应的摄像头硬件不存在时,该方法则返回空指针。
在得到Camera实例化对象后,可以查看该摄像头硬件的详细信息。调用该对象的getParameters()方法,得到返回值为android.hardware.Camera.Parameters摄像头参数类型的对象。在Camera.Parameters参数类型的对象中,可以使用getX系列方法获取包括闪光灯、聚焦、分辨率等系列信息;同时也可以使用setX系列方法重新调整设置包括闪光灯、聚焦、分辨率等系列信息。如果修改摄像头硬件的参数对象后,可以调用Camera摄像头对象的setParameters(Camera.Parameters params)方法,将修改后的参数应用到对应的摄像头硬件中。
要实现Camera摄像头的预览功能,只需要借助自定义控件类,该类继承自系统控件android.view.SurfaceView类。
在自定义控件类的构造方法中,传入上文获取的Camera摄像头对象作为该类的全局变量,以供在预览功能开启或关闭时调用摄像头对象的相关方法。
之后可以在自定义控件类内部调用自己的getHolder()方法,返回android.view.SurfaceHolder类型的对象,该对象是绑定当前SurfaceView控件与其中的控制信息的。可以调用该对象的setX系列方法设置当前自定义的SurfaceView中的显示信息,同时调用该对象的addCallback(SurfaceHolder.Callback callback)方法为当前自定义SurfaceView增加界面更新的回调,参数 callback 为回调接口android.view.SurfaceHolder.Callback实现的实例化对象。
在SurfaceHolder.Callback接口的实例化对象中,分别实现surfaceCreated(SurfaceHolder holder)在自定义控件创建时回调的方法,通常在该方法中调用当前类的全局变量Camera对象的setPreviewDisplay(holder)方法将摄像头与当前控件绑定,之后调用Camera对象的startPreview()方法启动摄像头的预览,这样摄像头采集的数据就会实时展示在当前自定义SurfaceView控件中了;surfaceChanged(SurfaceHolder holder, int format, int width, int height)在自定义控件包括后边三个参数所代表的信息发生改变时回调的方法,此时一般要先调用全局变量Camera对象的stopPreview()停止预览,之后完成该控件内部的一些更新信息,最后再重新调用Camera对象的setPreviewDisplay(holder)和startPreview()方法重新绑定并启动预览;surfaceDestroyed(SurfaceHolder holder)在自定义控件被销毁时回调的方法,通常在刚方法中会调用Camera对象的stopPreview()停止预览,最后调用release()方法直接释放相关资源,这样该Camera对象的相关数据便都清空了。
要实现摄像头的拍照功能,只需要调用Camera对象的takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback postview, Camera.PictureCallback jpeg)方法。其中参数 shutter 是拍照那一刻回调的android.hardware.Camera.ShutterCallback接口对象,在拍摄照片时,会回调该对象的唯一方法onShutter(),因此如果想在拍照时搞些小动作,可以在该对象的onShutter()中添加代码,通常该参数 shutter 为 null;
参数 raw 、 postview 、 jpeg 三个都是android.hardware.Camera.PictureCallback图片回调接口的实例化对象,在该对象中实现了onPictureTaken(byte[] data, Camera camera)方法,是摄像头采集到拍摄的数据后回调该方法,其中的 data 参数便是具体的照片数据,而 camera 则是对应的摄像头对象;三个参数不同的是,参数 raw 是返回的原始数据、参数 postview 是返回的是缩略图数据、参数 jpeg 则是返回的经过jpeg编码的压缩数据。
如果想实现实现摄像头的录制视频功能,在调用Camera对象的startPreview()方法开启预览后,还要调用其unlock()方法将该摄像头对象从当前进程解锁,以便之后将该摄像头对象配置到android.media.MediaRecorder多媒体录制类中,在多媒体录制类结束录制并关闭释放相关资源后,调用Camera对象的reconnect ()方法重新将该摄像头与当前进程锁定。这样便可以在当前进程中继续使用该摄像头对象了。
关于使用MediaRecorder多媒体录制类的相关流程,将在后续文章中详细讲解。
从Android5.0版本系统开始,可以在应用程序项目配置文件中增加androidx.camera:camera-core和androidx.camera:camera-camera2等官方提供的CameraX框架的依赖库。该库将摄像头的功能分别作为单独的类处理,而不是继续使用低版本将功能都添加到同一个Camera类中。
首先是检测设备是否支持摄像头硬件,同样是在能获取Context上下文环境对象的地方,借助androidx.camera.lifecycle.ProcessCameraProvider摄像头提供者类的静态方法getInstance(Context context)获取提供者的进程间唯一的单例对象,返回的是ListenableFuture<ProcessCameraProvider>类型的结果,这里的ListenableFuture是谷歌提供的 guava 框架下com.google.common.util包中的异步任务,简单来说就是该类型的对象可以调用addListener(Runnable runnable, Executor executor)监听方法,在该对象所绑定的异步任务完成后会回调监听方法中的参数 runnable 运行,而参数 executor 则指定了运行 runnable 所在的线程,通过使用ContextCompat.getMainExecutor(Context context)方法获取UI主线程的Executor对象。而这里通过摄像头提供者类的静态方法获取的单例对象,就是对应的异步任务,在返回ListenableFuture<ProcessCameraProvider>对象后,为该对象增加监听方法,在异步任务完成后才会调用监听方法中的内容。
在参数 runnable 定义的运行过程中,便可以直接使用之前的ListenableFuture<ProcessCameraProvider>对象的get()方法,返回ProcessCameraProvider类型的单例对象以实现摄像头功能。
同样可以调用ProcessCameraProvider对象的getAvailableCameraInfos()方法获取可以访问的摄像头详细信息,得到androidx.camera.core.CameraInfo摄像头信息对象组成的列表。
实现预览功能,主要依靠androidx.camera.view.PreviewView预览视图类作为系统控件来实时展示摄像头采集的数据。最终在代码中调用PreviewView对象的getSurfaceProvider()方法,可以获取androidx.camera.core.Preview.SurfaceProvider预览提供者类型的对象,为之后将该控件与androidx.camera.core.Preview预览类绑定。
之后需要创建androidx.camera.core.Preview预览类,其创建方式遵循建造者模式,构造androidx.camera.core.Preview.Builder建造者对象,使用该对象的setX系列方法可以配置预览信息,最终调用建造者对象的build()方法返回创建Preview预览类对象。
得到Preview对象后,调用setSurfaceProvider(Preview.SurfaceProvider surfaceProvider)方法绑定预览视图控件,参数 surfaceProvider 即上文预览视图控件对象中的Preview.SurfaceProvider类型的预览提供者对象。
最终,只需将该Preview对象绑定到ProcessCameraProvider摄像头提供者对象中,在上文获取到摄像头提供者的异步任务完成监听中,调用ProcessCameraProvider对象的bindToLifecycle (LifecycleOwner lifecycleOwner, CameraSelector cameraSelector, UseCase... useCases)方法将摄像头、预览、分别与当前界面生命周期绑定即可。其中参数 lifecycleOwner 为当前界面Activity 对象;
参数 cameraSelector 是通过建造者模式创建的androidx.camera.core.CameraSelector摄像头选择器对象,通过先构造androidx.camera.core.CameraSelector.Builder建造者对象,使用该对象的requireLensFacing(int lensFacing)方法来选择要使用的摄像头类型,其参数 lensFacing 值只能为前置摄像头的CameraSelector.LENS_FACING_FRONT=0或后置摄像头的CameraSelector.LENS_FACING_BACK=1,之后同样调用build()方法返回创建的CameraSelector对象;
可变参数 useCases 即包括上文中的Preview对象和下文的其他功能对应的案例对象。
实现拍照功能,主要依靠androidx.camera.core.ImageCapture图片捕获类。该类同样使用建造者模式创建,首先构造androidx.camera.core.ImageCapture.Builder建造者对象,调用该对象的setX系列方法,可以设置拍照时的参数信息,最终调用该对象的build()方法,返回创建的图片捕获对象。
在得到ImageCapture图片拍摄类对象后,同样需要调用ProcessCameraProvider摄像头提供者对象的bindToLifecycle (LifecycleOwner lifecycleOwner, CameraSelector cameraSelector, UseCase... useCases)方法将摄像头与当前拍照对象绑定,参数 lifecycleOwner 和 cameraSelector 与上文使用相同,而参数 useCases 则是这里的ImageCapture图片拍摄类对象。
最终在需要拍照的时刻,调用ImageCapture图片拍摄类对象的takePicture(ImageCapture.OutputFileOptions outputFileOptions, Executor executor, ImageCapture.OnImageSavedCallback imageSavedCallback)方法即可。其中,
参数 outputFileOptions 是用建造者模式的输出文件选项,同样是通过构造androidx.camera.core.ImageCapture.OutputFileOptions.Builder建造者,设置要保存的文件路径,最终建造返回androidx.camera.core.ImageCapture.OutputFileOptions类型对象使用即可;
参数 executor 是下一个参数 imageSavedCallback 回调方法被运行时所在的线程;
参数 imageSavedCallback 是androidx.camera.core.ImageCapture.OnImageCapturedCallback照片捕获后回调接口的实例化对象,在该对象中需要实现onCaptureSuccess(ImageProxy image)在图片拍摄成功时的回调方法,和onError(ImageCaptureException exception)在图片拍摄出错时的回调方法。
实现视频录制功能,主要依靠androidx.camera.video.VideoCapture视频捕获类。
这里的VideoCapture视频捕获类可就不是建造者模式创建的了,而是使用其静态方法withOutput(T videoOutput),传入参数 videoOutput 为视频输出流,返回VideoCapture的实例化对象。这里的视频输出流通常为androidx.camera.video.Recorder视频录制类型,Recorder视频录制类的对象是后面的操作对象,因此他才是用建造者模式创建的。
先构造androidx.camera.video.Recorder.Builder建造者,通过建造者对象的setQualitySelector(QualitySelector qualitySelector)方法为录制的视频流设置压缩质量,该方法的参数 qualitySelector 通常是由androidx.camera.video.QualitySelector质量选择器的静态方法getSupportedQualities(CameraInfo cameraInfo)获取支持的压缩质量列表,其值包括最低分辨率的QualitySelector.QUALITY_LOWEST=0、最高分辨率的QualitySelector.QUALITY_HIGHEST=2、480P分辨率的QualitySelector。QUALITY_SD=4、720P的QualitySelector.QUALITY_HD=5、1080P的QualitySelector.QUALITY_FHD=6、2160P的QualitySelector.QUALITY_UHD=8。在获取质量列表的静态方法中,参数 canmeraInfo 是录制使用的摄像头信息对象。最终调用建造者的build()方法,返回创建的Recorder录制视频流对象。
在得到VideoCapture视频捕获类对象后,同样需要调用ProcessCameraProvider摄像头提供者对象的bindToLifecycle (LifecycleOwner lifecycleOwner, CameraSelector cameraSelector, UseCase... useCases)方法将摄像头与当前视频捕获对象绑定,在参数 useCases 中增加VideoCapture对象即可。
在VideoCapture视频捕获类对象绑定之后,通过调用其getOutput()方法返回其设置的Recorder视频录制对象。
通过调用Recorder对象的prepareRecording(Context context, FileOutputOptions fileOutputOptions)方法准备录制视频,其参数 context 为上下文环境对象,参数 fileOutputOptions 与拍摄照片时类似的使用androidx.camera.video.FileOutputOptions输出文件选项对象,用以设置录制视频的保存路径。该方法返回androidx.camera.video.PendingRecording预备录制类型的对象。
在得到的PendingRecording对象中,可以调用start()方法,启动视频录制,返回androidx.camera.video.ActiveRecording活动录制类型对象。
在得到的ActiveRecording对象中,可以调用pause()方法暂停录制,resume()方法继续录制,stop()方法停止录制。如此,便可完成视频的录制流程。
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于