- 版本:1.0.1
- GitHub: https://github.com/VoiceThread/nativescript-plugins
- NPM: https://npmjs.net.cn/package/%40voicethread%2Fnativescript-camera
- 下载
- 昨日: 0
- 上周: 0
- 上个月: 3
NativeScript Camera
@voicethread/nativescript-camera
内容
安装
npm install @voicethread/nativescript-camera --save
或
ns plugin install @voicethread/nativescript-camera
特性
此 Nativescript Camera 插件适用于 Android(API 26+)和 Apple(iOS 12+)设备,具有以下特性
- 📷 照片和视频拍摄模式
- 👁️ 在视频录制期间切换摄像头,并可选择在录制时锁定设备方向
- 👌 捏合缩放和轻触对焦
- 📱 视频合并工具
- 🎞️ 内置闪光灯、摄像头切换和摄像头按钮
- 📸 照片和视频模式中闪光灯/手电筒控制
- ⏱️ 支持方形裁剪照片并将照片/视频保存到设备照片库
- 🧩 带内置预览界面的照片确认选项
- 🔍 可自定义输出照片尺寸和质量(保存为 jpeg 格式)
未来特性
- ⏯️ 可自定义视频编解码器和尺寸
- 🌓 视频确认标志和用户界面
- ⚡ 提供更多控制摄像头和照片/视频捕获的选项
用法
了解如何使用此插件的最佳方法是查看此存储库中包含的演示应用程序。在 apps/demo/
文件夹中包含一个简单的 NS TypeScript 应用程序,该应用程序使用此插件。查看 apps/demo/src/plugin-demos/nativescript-camera.ts
和 apps/demo/src/plugin-demos/nativescript-camera.xml
以了解相机插件的使用,以及 apps/demo/src/main-view-model.ts
以在使用相机插件之前获取权限。
- 导入插件。
import { NSCamera } from '@voicethread/nativescript-camera';
- 通过 JS/TS 或 XML 创建相机实例
this.cam = new NSCamera();
this.cam.id = "nscamera"
this.cam.enableVideo = true;
this.cam.confirmPhotos = true;
this.cam.defaultCamera = 'front';
......
//Check camera and microphone permissions first.
//Then, add this.cam to a Layout as a child and voila!
或
<Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:Cam="@voicethread/nativescript-camera">
......
<Cam:NSCamera height="{{ cameraHeight }}"
id="nscamera"
defaultCamera="front"
enableVideo="true"
disablePhoto="false"
saveToGallery="true"
showCaptureIcon="true"
showToggleIcon="true"
showFlashIcon="true"
confirmPhotos="true"
autoSquareCrop="false"
insetButtons="true"
insetButtonsPercent="0.02"
shouldLockRotation="true"
confirmRetakeText="nah"
confirmSaveText="yeah"
maxDimension="800"
quality="90"
debug="true">
</Cam:NSCamera>
......
- 连接到相机事件以处理视频和照片捕获事件以及其他有用的事件。
this.cam.on(NSCamera.errorEvent, args => {
//handle error
});
this.cam.on(NSCamera.toggleCameraEvent, (args: any) => {
// update some UI/state
});
this.cam.on(NSCamera.photoCapturedEvent, (args: any) => {
// args.data should be the path of the jpeg file produced by camera library
});
this.cam.on(NSCamera.videoRecordingReadyEvent, (args: any) => {
//args.data should be the path of the file created with the video recording
});
this.cam.on(NSCamera.videoRecordingStartedEvent, (args: any) => {
// update some UI/state
});
this.cam.on(NSCamera.videoRecordingFinishedEvent, (args: any) => {
// some other UI updates
});
this.cam.on(NSCamera.cameraReadyEvent, (args: any) => {
// lets you know once native camera instance is ready and initialized
});
- 使用内置按钮或通过应用程序中公开的功能控制相机。
权限
在创建/使用 Camera 实例之前,您需要确保用户已授予摄像头和麦克风的权限。社区权限插件的示例可以在 apps/demo/src/main-view-model.ts
中看到。
Android 权限
在演示应用程序中请求权限时,我们使用 @nativescript-community perms 插件。
确保您的 AndroidManifest.xml 包含以下声明。
<manifest ... >
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
为了支持 API<29 设备保存到照片库,还需要在 AndroidManifest.xml 中添加以下行
<manifest ... >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
在您的应用程序中,如果您想使用 saveToGallery
标志,请确保请求这些权限。您可以在 apps/demo/src/plugin-demos/nativescript-camera.ts
中看到示例。如果此标志已设置且未授予权限,则不会将副本保存到设备照片。
iOS 权限
将以下内容添加到 app/App_Resources/iOS/Info.plist
<key>NSMicrophoneUsageDescription</key>
<string>This app requires access to your microphone to record audio</string>
<key>NSCameraUsageDescription</key>
<string>This app requires access to your camera to record video and take pictures</string>
如果您想使用 saveToGallery
标志,则需要添加以下内容并从用户那里请求权限(查看 apps/demo/src/plugin-demos/nativescript-camera.ts
中的有效示例)。如果此标志已设置且未授予权限,则不会将副本保存到照片库。
<key>NSPhotoLibraryUsageDescription</key>
<string>Requires access to photo library to upload media.</string>
注意:如果您在生产应用中使用权限插件,请首先阅读其README.md,因为在生产应用中使用此插件可能需要您添加所有iOS Info.plist权限字符串,以避免因插件包含所有权限类型的代码而被自动处理拒绝。
属性
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
debug | 布尔型 | false | 如果为true,日志将被输出到控制台以帮助调试Camera插件。 |
confirmPhotos | 布尔型 | true | 如果为true,默认的拍照事件在保存之前将显示确认对话框。 |
confirmRetakeText | 字符串 | '重拍' | 在确认捕获时,此文本将被显示给用户以便重新拍照。 |
confirmSaveText | 字符串 | '保存' | 在确认捕获时,此文本将被显示给用户以便保存照片。 |
saveToGallery | 布尔型 | true | 如果为true,插件捕获的照片或视频将被保存到设备相册。 |
showFlashIcon | 布尔型 | true | 如果为true,默认的闪光灯切换图标/按钮将显示在NSCamera布局上。注意:如果当前相机没有手电筒,这将被自动隐藏。 |
showToggleIcon | 布尔型 | true | 如果为true,默认的前后摄像头切换图标按钮将显示在NSCamera布局上。 |
showCaptureIcon | 布尔型 | true | 如果为true,默认的捕获(拍照)图标/按钮将显示在NSCamera布局上。 |
showGalleryIcon | 布尔型 | true | 如果为true,从相册/图库选择图标/按钮将显示在NSCamera布局上。 |
enableVideo | 布尔型 | false | 如果为true,Camera实例可以录制视频,并将影响相机UX和主摄像头按钮图标。 |
disablePhoto | 布尔型 | false | 如果为true,Camera实例UI将只允许视频模式操作。如果enableVideo为false且disablePhoto为true,主摄像头按钮将不会触发任何操作。 |
defaultCamera | 'front' 或 'rear' |
'rear' | 启动时使用的摄像头。'front' 或'rear' 。 |
shouldLockRotation | 布尔型 | true | 如果为true,在录制视频时锁定设备方向。 |
Android专用属性
名称 | 类型 | 描述 |
---|---|---|
flashOnIcon | 字符串 | 闪光灯开启时(启用)的原生图像按钮的app_resource drawable名称。 |
flashOffIcon | 字符串 | 闪光灯关闭时(禁用)的原生图像按钮的app_resource drawable名称。 |
toggleCameraIcon | 字符串 | 切换摄像头按钮的app_resource drawable名称。 |
takePicIcon | 字符串 | 拍照(捕获)按钮的app_resource drawable名称。 |
galleryIcon | 字符串 | 打开相册(图库)按钮的app_resource drawable名称。 |
autoFocus | 布尔型 | 如果为true(默认为true),当相机检测到目标变化时,相机将使用连续对焦。 |
insetButtons | 布尔型 | 如果为true(默认为false),调整内置按钮与屏幕边缘的距离。 |
insetButtonsPercent | 数字 | 缩进的百分比,范围从0.0到1.0 |
仅限iOS属性
名称 | 类型 | 描述 |
---|---|---|
doubleTapCameraSwitch | 布尔型 | 启用/禁用双击手势切换摄像头。(启用) |
跨平台公共方法
方法 | 描述 |
---|---|
isCameraAvailable() | 如果设备至少有一个摄像头,则返回true。 |
toggleFlash() | 切换活动相机的闪光灯模式。 |
toggleCamera() | 切换设备上的活动摄像头。 |
takePicture(opts?: ICameraOptions) | 拍摄当前相机预览的照片。当图像文件保存时,将发出带有其路径的photoCapturedEvent 事件。 |
getFlashMode(): string | Android:可能的字符串:https://android-docs.cn/reference/android/hardware/Camera.Parameters.html#getFlashMode() iOS:可以是'on' 或'off' |
record(opts?: IVideoOptions) | 开始录制视频。 |
stop() | 停止视频录制。当视频文件准备就绪时,将发出带有其路径的videoRecordingReadyEvent 事件。 |
仅适用于Android的公共方法
方法 | 描述 |
---|---|
getNumberOfCameras() | 返回设备上的相机数量。 |
hasFlash() | 如果活动相机具有闪光模式,则返回true。 |
事件
名称 | 描述 |
---|---|
errorEvent | 当相机发出错误时执行。 |
photoCapturedEvent | 拍照时执行。 |
toggleCameraEvent | 当设备相机切换时执行。 |
videoRecordingStartedEvent | 当开始录制视频时执行。 |
videoRecordingFinishedEvent | 当停止录制视频但尚未处理时执行。 |
videoRecordingReadyEvent | 当视频完成处理并准备好使用时执行。 |
confirmScreenShownEvent | 当显示图片确认对话框时执行。 |
confirmScreenDismissedEvent | 当通过重拍或保存按钮关闭图片确认对话框时执行。 |
cameraReadyEvent | 当相机实例完成初始化时执行。 |
选项接口
拍照选项
export interface ICameraOptions {
confirmPhotos?: boolean;
saveToGallery?: boolean; //shared with video options
quality?: number;
maxDimension?: number;
autoSquareCrop?: boolean;
confirmRetakeText?: string;
confirmSaveText?: string;
}
视频录制选项
export interface IVideoOptions {
videoQuality?: CameraVideoQuality; //defaults to 720p
saveToGallery?: boolean; //shared with photo options
androidMaxVideoBitRate?: number; //Android-only
androidMaxFrameRate?: number; //Android-only
androidMaxAudioBitRate?: number; //Android-only
}
export enum CameraVideoQuality {
MAX_480P = '480p',
MAX_720P = '720p',
MAX_1080P = '1080p',
MAX_2160P = '2160p',
HIGHEST = 'highest',
LOWEST = 'lowest',
QVGA = 'qvga',
}
注意事项
音频输入 - 在iOS上,插件将优先使用以下顺序的可用音频输入:蓝牙、有线和内置。在Android上,插件目前仅使用内置设备麦克风。将来将添加对蓝牙设备的支持。
应用程序挂起和恢复 - 您应添加将销毁Camera View并重新初始化的事件监听器,以避免设备相机访问问题。您可以在演示应用程序中查看示例。
捏合缩放 - 对于iOS,目前此功能仅支持后置相机。未来可能添加对前置相机的支持。
主相机按钮 - 对于两个平台,主相机按钮在视频录制模式下支持点击和长按手势。点击以开始/停止录制,或长按按钮直到停止按按钮以录制。在照片模式下,长按被忽略。
相机预览模式 - 如果enableVideo为false且disablePhoto为true,则相机插件将仅在相机预览模式下运行。在此模式下,即使启用了这些选项,也不会渲染主相机按钮或闪光按钮。
设备睡眠 - 开发者应处理在视频录制期间禁用设备睡眠,以避免使用相机插件时设备/应用程序挂起。
设备方向锁定 - 如果您的应用程序有自己的方向管理系统,请使用该系统而不是插件标志,以确保一致的行为,尤其是在iOS上。
录制期间的高分辨率和相机切换 - 不是所有相机在相同设备上都支持相同的分辨率范围,因此您将体验到使用高分辨率相机开始录制并在切换到仅支持较低分辨率的相机时记录的失真。
工具
此插件包含一些对开发者可能有用的实用函数
mergeVideoFiles(inputFiles: string[], outputPath: string): Promise<File>
:合并由相机插件生成的多个视频文件。要使用它,所有输入视频文件都必须是具有相同视频/音频编解码器和分辨率的MP4。函数接受两个参数;第一个是输入视频文件名数组,第二个是将合并的视频文件保存到路径的字符串。
let outputFile = await this.cam.mergeVideoFiles(videoSegmentsArray, outputPath)
getVideoCodec(videoPath: string): string
:根据路径查找视频文件的编解码器/格式信息。
console.log('codec:', this.cam.getVideoCodec(args.data));
getVideoResolution(videoPath: string): { width: number; height: number }
:根据路径查找视频文件的高度和宽度信息。
console.log('Height/width:', this.cam.getVideoResolution(args.data));
getVideoDuration(videoPath: string): number
:根据路径查找视频文件的持续时间(以毫秒为单位)。
console.log('video duration: ', this.cam.getVideoDuration(args.data));
致谢
本插件基于NS平台的Nativescript-Camera-Plus,iOS平台的SwiftyCam以及Android平台的FancyCamera。
许可
Apache License Version 2.0