设置和切换前后摄像头(H5)
更新时间: 2024/09/18 16:26:13
在 HTML5 竖屏应用上设置或者切换前/后置摄像头时,部分设备或者机型可能会产生一些不符合预期的问题,如摄像头切换失败、黑屏等。
本文介绍在移动端 H5 应用上如何正确的使用相关接口设置,保障摄像头设置或切换可以正常操作。
实现步骤
H5 的前/后置摄像头通过 facingMode
配置。
-
在调用
createStream
创建本地流时,可以通过设置facingMode
参数来指定视频采集的前/后置摄像头。在部分设备中'environment'会默认选中异常设备,建议此处传入'user',如需使用后置摄像头,请参考最后的示例代码,传入设备 ID 实现。JavaScript
// 创建 localStream localStream = NERTC.createStream({ audio: true, video: true, uid: 123, facingMode: 'user' // 'user' 为前置摄像头,'environment' 为后置摄像头 });
-
如果是 iOS 设备,在调用
open
开启视频采集设备时,可以通过设置facingMode
参数来指定视频采集前/后置摄像头。JavaScript
//当前有可能没有开启摄像头,不过执行 close 也不影响什么 await rtc.localStream.close({ type: 'video' }) // 开启摄像头 rtc.localStream.open({type:'video',deviceId:'xxxx',facingMode:'user'}).then(async ()=>{ console.log('打开成功') // 本地播放 }).catch(err =>{ console.log('打开失败: ', err) })
-
如果是安卓设备,在切到前置时,仍可以使用
facingMode:'user'
参数实现,如果是前置切到后置,使用facingMode:'environment'
参数会导致偶现黑屏,视频画面放大等问题,此时建议使用deviceId
完成切换。JavaScript
//当前有可能没有开启摄像头,不过执行 close 也不影响什么 await rtc.localStream.close({ type: 'video' }) //安卓手机利用 deviceId 来指定单一的后置摄像头 const cameraList = await NERTC.getCameras() //NERTC.getCameras 经根据排列组合,帮您处理好每个厂商暴露出来给网易云信使用的设备序列。部分设备(例如华为)会把闪光灯也包括在内,并暴露多个前后置给您使用,后置网易云信取最后一个设备。 const cameraDevice = cameraList[cameraList.length - 1] if (cameraDevice && cameraDevice.label && cameraDevice.label.includes('back')) { console.log('摄像头列表中的最后一位确认是后置摄像头,且当前已经有了摄像头权限') } else { console.warn( '当前环境不是 H5,或者当前环境还没有摄像头权限, 打印 cameraDevice: ', JSON.stringify(cameraDevice, null, '') ) } try { await rtc.localStream.open({ type: 'video', deviceId: cameraDevice.deviceId //使用 deviceId 指定后置摄像头 }) console.log('打开摄像头 sucess') await rtc.localStream.play(document.getElementById('local-container')) rtc.localStream.setLocalRenderMode(globalConfig.localViewConfig) } catch (e) { console.error('H5 使用 facingMode 参数开启摄像头失败', e.message) if (e.message.includes('NotReadableError')) { } }
完整示例代码
JavaScriptif (!rtc.localStream) {
console.warn('当前没有初始化 localStream')
return
}
//当前有可能没有开启摄像头,不过执行 close 也不影响什么。
await rtc.localStream.close({
type: 'video'
})
const USER_AGENT = (window.navigator && window.navigator.userAgent) || ''
const IS_IPAD = /iPad/i.test(USER_AGENT)
const IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD
const IS_IPOD = /iPod/i.test(USER_AGENT)
const IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD
if (IS_IOS) {
//苹果手机直接遵守 facingMode 的设置,所以直接利用该属性完成切换,无需处理 deviceId。
try {
await rtc.localStream.open({
type: 'video',
facingMode
})
console.log('打开摄像头 sucess')
await rtc.localStream.play(document.getElementById('local-container'))
rtc.localStream.setLocalRenderMode(globalConfig.localViewConfig)
} catch (e) {
console.error('IOS 端 H5 使用 facingMode 参数开启摄像头失败', e.message)
if (e.message.includes('NotReadableError')) {
}
}
} else {
//facingMode 参数目前实际测试看,安卓手机前置支持情况还可以,后置表现却是各有千秋,表现诸如选错摄像头、黑屏等问题。
if (facingMode === 'user') {
try {
await rtc.localStream.open({
type: 'video',
facingMode
})
console.log('打开摄像头 sucess')
await rtc.localStream.play(document.getElementById('local-container'))
rtc.localStream.setLocalRenderMode(globalConfig.localViewConfig)
} catch (e) {
console.error('安卓端 H5 使用 facingMode 参数开启摄像头失败', e.message)
if (e.message.includes('NotReadableError')) {
}
}
} else {
//安卓手机利用 deviceId 来指定单一的后置摄像头。
const cameraList = await NERTC.getCameras()
//NERTC.getCameras 经根据排列组合,帮您处理好每个厂商暴露出来给网易云信使用的设备序列。部分设备(例如华为)会把闪光灯也包括在内,并暴露多个前后置给您使用,后置网易云信取最后一个设备。
const cameraDevice = cameraList[cameraList.length - 1]
if (cameraDevice && cameraDevice.label && cameraDevice.label.includes('back')) {
console.log('摄像头列表中的最后一位确认是后置摄像头,且当前已经有了摄像头权限')
} else {
console.warn(
'当前环境不是 H5,或者当前环境还没有摄像头权限, 打印 cameraDevice: ',
JSON.stringify(cameraDevice, null, '')
)
}
try {
await rtc.localStream.open({
type: 'video',
deviceId: cameraDevice.deviceId //使用 deviceId 指定后置摄像头
})
console.log('打开摄像头 sucess')
await rtc.localStream.play(document.getElementById('local-container'))
rtc.localStream.setLocalRenderMode(globalConfig.localViewConfig)
} catch (e) {
console.error('H5 使用 facingMode 参数开启摄像头失败', e.message)
if (e.message.includes('NotReadableError')) {
}
}
}
}
此文档是否对你有帮助?