最近接了个家庭安防项目,客户要求用手机就能随时查看家里的监控画面。经过技术选型,最终决定用UniApp来实现这个功能。这里分享下我的实战经验,从权限申请到视频传输的全过程都会讲到,特别适合刚接触这个领域的朋友。
UniApp最大的优势就是跨平台,一套代码可以同时跑在iOS和Android上。我用的是Vue.js语法,这对前端开发者特别友好。在实际测试中,我发现UniApp的摄像头API调用起来比原生开发简单不少,而且性能表现也相当不错。
说到视频传输,WebRTC和RTMP这两个协议我都试过。WebRTC更适合点对点实时通信,延迟可以做到很低;而RTMP在直播场景下更稳定。具体选哪个要看项目需求,后面我会详细对比它们的实现差异。
首先确保你的开发环境已经就绪。我用的HBuilderX,这是DCloud官方推荐的IDE,对UniApp支持最好。安装时记得勾选"小程序组件"和"5+App"模块,这些都是后面要用到的。
创建新项目时选择"uni-app"模板,模板类型选"默认模板"就行。项目创建完成后,先别急着写代码,把这几件事做了:
这里有个坑我踩过:不同平台对权限的处理方式不一样。Android需要在manifest里声明权限,而iOS除了配置还要动态申请。UniApp提供了统一的API,但实际调用时还是要注意平台差异。
javascript复制// 权限申请示例
uni.authorize({
scope: 'scope.camera',
success() {
console.log('已授权摄像头权限')
},
fail() {
uni.showModal({
content: '需要摄像头权限才能使用该功能',
confirmText: '去设置',
success(res) {
if (res.confirm) {
uni.openSetting()
}
}
})
}
})
UniApp提供了<camera>组件,用起来很简单。但要注意几个关键属性:
html复制<template>
<view>
<camera ref="myCamera"
style="width:100%;height:400px"
device-position="back"
flash="off">
</camera>
<button @tap="switchCamera">切换摄像头</button>
</view>
</template>
除了基本拍摄,我们还需要实现:
这里有个实用技巧:通过ref获取camera实例后,可以调用原生方法。比如切换摄像头的代码:
javascript复制methods: {
switchCamera() {
const current = this.devicePosition
this.devicePosition = current === 'back' ? 'front' : 'back'
}
}
WebRTC特别适合实时性要求高的场景。在UniApp中实现WebRTC需要引入适配器:
javascript复制import adapter from 'webrtc-adapter'
建立连接的步骤:
实测延迟可以控制在300ms以内,但要注意iOS上的特殊限制。
如果对实时性要求不高,RTMP是个更稳定的选择。需要搭建媒体服务器,我用的是Nginx+RTMP模块。客户端代码相对简单:
javascript复制const rtmpUrl = 'rtmp://your-server.com/live/streamkey'
this.$refs.myCamera.start({
url: rtmpUrl,
success() {
console.log('推流开始')
}
})
不同设备的摄像头参数差异很大。我整理了几个常见问题:
解决方案是做好设备检测和适配:
javascript复制uni.getSystemInfo({
success(res) {
console.log(res.platform, res.model)
// 根据设备类型调整参数
}
})
视频传输很耗资源,这几个优化点很关键:
在UniApp中可以通过camera组件的属性控制:
html复制<camera resolution="high" frame-rate="30"></camera>
视频监控涉及隐私,必须重视安全性。我建议做到以下几点:
在代码实现上,可以这样加强安全:
javascript复制uni.request({
url: 'https://secure-server.com/api',
header: {
'Authorization': 'Bearer ' + token
},
data: {
// 加密后的数据
}
})
在最近的项目中,我发现几个值得注意的点:
针对这些问题,我的解决方案是:
javascript复制// 网络检测示例
uni.onNetworkStatusChange((res) => {
if(res.networkType === 'none') {
this.showToast('网络已断开')
}
})
整个项目做下来,最大的体会是:视频功能开发不能只关注功能实现,用户体验和性能优化同样重要。特别是在移动端,要考虑电量消耗、流量消耗这些实际问题。