@angelengineering/camera
Nativescript 应用程序的相机插件
npm i --save @angelengineering/camera

@angelengineering/camera

NativeScript 相机 apple android

npm

内容


安装

npm install @angelengineering/camera --save

或者

ns plugin install @angelengineering/camera

特性

此 Nativescript 相机插件适用于 Android (API 26+) 和 Apple (iOS 12+) 设备,并具有以下功能

  • 📷 照片和视频捕获模式
  • 👁️ 在视频录制期间切换相机,并在录制时锁定设备方向
  • 👌 捏合放大/缩小和轻触对焦
  • 📱 视频合并工具
  • 🎞️ 内置按钮用于闪光灯、相机切换和捕获
  • 📸 在照片和视频模式下控制闪光灯/手电筒
  • ⏱️ 支持方形裁剪照片并将照片/视频保存到设备照片库
  • 🧩 内置 UI 显示预览的图片确认选项

未来功能

  • 🌓 视频确认标志和 UI(您现在可以使用 @angelengineering/videoplayer 来创建自己的确认流程)
  • ⚡ 提供更多选项以更好地控制相机和照片/视频捕获

用法

了解如何使用此插件的最佳方式是查看本存储库中包含的演示应用程序。在 apps/demo/ 文件夹中包含一个简单的 NS TypeScript 应用程序,该应用程序使用此插件。查看 apps/demo/src/plugin-demos/camera.tsapps/demo/src/plugin-demos/camera.xml 以了解相机插件的使用,以及 apps/demo/src/main-view-model.ts 以在使用相机插件之前获取权限。

  1. 导入插件。
import { NSCamera } from '@angelengineering/camera';
  1. 通过 JS/TS 或 XML 创建相机实例
this.cam = new NSCamera();
this.cam.id = "nscamera"
// Decide if the camera should be in video or photo mode and set the enableVideo property.
this.cam.enableVideo = true;
this.cam.defaultCamera = 'front';
......
// Check camera and microphone permissions, then add `this.cam` to a Layout as a child view and voila!

<Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:Cam="@angelengineering/camera">
......
<Cam:NSCamera height="{{ cameraHeight }}"
id="nscamera"
debug="true"
enableVideo="true"
defaultCamera="rear"
showCaptureIcon="true"
showToggleIcon="true"
showFlashIcon="true"
insetButtons="true"
insetButtonsPercent="0.02"
shouldLockRotation="false"
confirmPhotos="true"
saveToGallery="true"
autoSquareCrop="false"
confirmRetakeText="nah"
confirmSaveText="yeah"
quality="95"
doubleTapCameraSwitch="true"
videoQuality="720p">

</Cam:NSCamera>
......
  1. 通过挂钩相机事件来处理视频和照片捕获事件以及其他有用的事件。
    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
});
  1. 使用内置按钮或使用您的应用程序中的公开功能来控制相机。

权限

在创建/使用 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/camera.ts 中看到一个示例。如果设置了此标志且未授予权限,则不会将副本保存到设备照片。

对于 Android,如果相机在照片模式下启动,则只需请求/要求相机权限。对于视频模式,则需要相机和麦克风权限。

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/camera.ts 中的示例以获取工作示例)。如果设置了此标志且未授予权限,则不会将副本保存到照片库。

  <key>NSPhotoLibraryUsageDescription</key>
<string>Requires access to photo library to upload media.</string>

注意:如果您在生产应用中使用 perms 插件,请务必首先阅读其 README.md,因为在生产应用中使用此插件可能需要您添加所有 iOS Info.plist 权限字符串,以避免因插件包含所有权限类型的代码而被自动处理拒绝。

对于 iOS,无论是照片还是视频模式,都需要相机和麦克风权限。


属性

名称 类型 默认值 描述
debug 布尔型 false 如果为真,将在 NS 和原生控制台输出日志,以帮助调试 Camera 插件。
confirmPhotos 布尔型 true 如果为真,默认的拍照事件在保存之前将显示确认对话框。
confirmRetakeText 字符串 '重拍' 在确认捕获时,此文本将显示给用户以重拍照片。
confirmSaveText 字符串 '保存' 在确认捕获时,此文本将显示给用户以保存照片。
saveToGallery 布尔型 true 如果为真,则插件捕获的照片或视频将保存到设备照片库。
showFlashIcon 布尔型 true 如果为真,则默认的闪光灯切换图标/按钮将在 NSCamera 布局上显示。注意:如果当前相机没有手电筒,则此按钮将自动隐藏。
showToggleIcon 布尔型 true 如果为真,则默认的相机切换(前后)图标按钮将在 NSCamera 布局上显示。
showCaptureIcon 布尔型 true 如果为真,则默认的捕获(拍照)图标/按钮将在 NSCamera 布局上显示。
showGalleryIcon 布尔型 true 如果为真,则从库中选择图标/按钮将在 NSCamera 布局上显示。
enableVideo 布尔型 false 如果为真,Camera 实例将处于视频模式,否则为照片模式。
defaultCamera 'front''rear' 'rear' 启动时使用的相机。 'front''rear'
shouldLockRotation 布尔型 true 如果为真,则在录制视频时锁定设备方向。
doubleTapCameraSwitch 布尔型 true 启用/禁用双击手势切换相机。

仅限 Android 属性

名称 类型 描述
flashOnIcon 字符串 当闪光灯开启(启用)时,用于原生图像按钮的应用资源可绘制名称。
flashOffIcon 字符串 当闪光灯关闭(禁用)时,用于原生图像按钮的应用资源可绘制名称。
toggleCameraIcon 字符串 用于切换相机按钮的应用资源可绘制名称。
takePicIcon 字符串 用于拍照(捕获)按钮的应用资源可绘制名称。
galleryIcon 字符串 用于打开库(图像库)按钮的应用资源可绘制名称。
autoFocus 布尔型 如果为真(默认为真),则当相机检测到目标变化时,将使用连续对焦。在 iOS 上,如果支持,将启用自动对焦。
insetButtons 布尔型 如果为真(默认为假),则调整内置按钮与屏幕边缘的间距。
insetButtonsPercent 数字 要缩进的百分比,范围从 0.0 到 1.0

跨平台公共方法

方法 描述
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事件并带有其路径。注意:这仅在视频模式下有效。
hasTorch() 如果活动相机在视频录制时有手电筒模式,则返回true。 注意:Android将仅返回hasFlash()
hasFlash() 如果活动相机有用于拍照的闪光灯模式,则返回true。更多详情请见下面的注意事项部分。
getNumberOfCameras() 返回设备上的相机数量。 注意:应该在接收到cameraReadyEvent之后调用,以确保插件已初始化并且可以访问相机硬件

事件

名称 描述
errorEvent 当Camera发出错误时执行。
photoCapturedEvent 拍照时执行。
toggleCameraEvent 设备相机切换时执行。
videoRecordingStartedEvent 开始录制视频时执行。
videoRecordingFinishedEvent 视频停止录制但尚未处理时执行。
videoRecordingReadyEvent 视频处理完成并准备使用时执行。
confirmScreenShownEvent 当显示图片确认对话框时执行。
confirmScreenDismissedEvent 当通过重拍或保存按钮取消图片确认对话框时执行。
cameraReadyEvent 当相机实例初始化完成后执行。

选项接口

拍照选项

export interface ICameraOptions {
confirmPhotos?: boolean;
saveToGallery?: boolean; //shared with video options
quality?: 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,这仅支持后置摄像头。

主相机按钮 - 对于两个平台,主相机按钮在视频录制模式下支持点击和长按手势。点击开始/停止录制,或长按按钮直到停止按住按钮来录制。在拍照模式下,长按将被忽略。

设备休眠 - 开发者应处理在视频录制期间禁用设备休眠,以避免在使用相机插件时设备/应用挂起。

设备方向锁定 - 如果您的应用有自己的方向管理系统,请使用它而不是插件标志,以确保一致的行为,尤其是在iOS上。

高分辨率和录制期间相机切换 - 并非所有相机都支持同一设备上相同范围的分辨率,因此您将在以高分辨率相机开始并切换到仅支持较低分辨率的相机时录制视频时体验到扭曲。

录制期间闪光灯控制 - 对于两个平台,闪光灯/手电筒图标(如果启用了该属性)将在视频录制期间隐藏,因为在录制期间打开或关闭此功能不受支持。

iOS上的闪光灯控制和前置摄像头 - 自iPhone 6s以来,iOS设备有一个名为Retina Flash的模式,将使用设备显示屏显示明亮的白色屏幕,同时使用前置摄像头拍照(如果启用了闪光灯模式)。后置摄像头将使用设备闪光灯硬件。

视频编解码器 - 视频将使用h264或h265压缩录制,具体取决于设备和操作系统版本。

工具

本插件包含一些可能对开发者有用的实用函数

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许可证版本2.0