这是我打算做的示例演示。 如果有人对使此修复程序起作用或有任何新逻辑有任何想法,请共享。
此演示通过使用mediaStream API和 使用react-webcam库,该库实际上提供了在名为videoConstraints = {faceingMode:'user'或'environment'}的道具的帮助下管理摄像机视图的选项,但似乎无法正常工作。 当我单击摄像头开关时,ICON屏幕只是挂起,什么也没有显示,并且有时它出乎意料地工作,所以最终我不得不跳到本机API解决方案,该解决方案显示了下面的代码。 衷心感谢。
start() {
if (window.stream) {
console.log('found stream and clearing that', window.stream)
window.stream.getTracks().forEach(function(track) {
track.stop()
})
}
const constraints = {
video: true,
audio: false
}
return navigator.mediaDevices
.getUserMedia(constraints)
.then(this.gotStream)
.then(this.gotDevices)
.catch(this.handleError);
}
gotStream(stream) {
window.stream = stream // make stream available to console
// video.srcObject = stream;
// Refresh button list in case labels have become available
console.log('enumerating media devices ')
return navigator.mediaDevices.enumerateDevices()
}
gotDevices(mediaDevices) {
const { availableVideoInputs, videoConstraints } = this.state
mediaDevices.forEach(mediaDevice => {
// console.log(mediaDevice)
if (mediaDevice.kind === 'videoinput') {
console.log('found new video input ', mediaDevice)
availableVideoInputs.push({
deviceId: mediaDevice.deviceId,
label: mediaDevice.label
})
// availableVideoInputs.push('mediaDevice.deviceId.availableVideoInputs.push(mediaDevice.deviceId)')
}
})
console.log('aggregated availableVideoInputs new ', availableVideoInputs)
if (availableVideoInputs.length > 0) {
// there are accessible webcam
// setting first device as default to open
const tempVideoConstraint = {...videoConstraints}
if (availableVideoInputs[0].deviceId) {
console.log('availableVideoInputs[0] = ', availableVideoInputs[0])
tempVideoConstraint.deviceId = availableVideoInputs[0].deviceId
}
// console.log('putting tempVideoConstraint.facingMode ', tempVideoConstraint)
// if (availableVideoInputs[0].label.includes('back')) {
// tempVideoConstraint.facingMode = { exact: 'environment'}
// } else {
// // it is now turn to set front active
// tempVideoConstraint.facingMode = 'user'
// }
console.log('setting new video constrains ', tempVideoConstraint)
// this.setState({
// availableVideoInputs,
// // activeVideoInputID: availableVideoInputs[0].deviceId,
// // videoConstraints: tempVideoConstraint
// })
this.updateAvailableVideoStream(availableVideoInputs)
return Promise.resolve('done setting updateAvailableVideoStream')
} else {
// no webcam is available or accessible
console.error('ERR::VIDEO_STREAM_NOT_AVAILABLE')
}
}
updateAvailableVideoStream(availableVideoInputs) {
this.setState({ availableVideoInputs })
}
componentDidMount() {
this.start()
.then(data => {
console.log('data ', data)
console.log('update state ', this.state)
this.setState({
videoConstraints: {
...this.state.videoConstraints,
facingMode: 'user'
}
})
})
}
handleCameraSwitch() {
const { videoConstraints, availableVideoInputs, activeVideoInputID } = this.state
console.log('current video constraints ', videoConstraints)
const tempVideoConstraint = { ...videoConstraints }
// now check if it is possible to change camera view
// means check for another webcam
console.log({ availableVideoInputs })
console.log({ activeVideoInputID })
console.log({ remainingVideoStreams })
if (availableVideoInputs.length === 1) {
// cannot change the webcam as there is only 1 webcam available
console.error('ERR - cannot change camera view [Available Video Inputs: 1]')
return
}
// now change the view to another camera
// get the current active video input device id and filter then from available video stream
const remainingVideoStreams = availableVideoInputs.filter(videoStream => videoStream.deviceId !== activeVideoInputID)
// now check if in remainingVideoStreams there is more than 1 stream available to switch
// if available then show the Stream Selection List to user
// else change the stream to remainingVideoStreams[0]
console.log({ availableVideoInputs })
console.log({ activeVideoInputID })
console.log({ remainingVideoStreams })
if (remainingVideoStreams && remainingVideoStreams.length === 1) {
tempVideoConstraint.deviceId = remainingVideoStreams[0].deviceId
console.log('new video constraints ', {...tempVideoConstraint})
console.log('webcam ref ', this.webCamRef.current)
// if (remainingVideoStreams[0].label.includes('back') || tempVideoConstraint.facingMode === 'user') {
// tempVideoConstraint.facingMode = { exact: 'environment' }
// } else {
// // it is now turn to set front active
// tempVideoConstraint.facingMode = 'user'
// }
console.log('new video constraints with facing mode', tempVideoConstraint)
// const constraints = {
// video: tempVideoConstraint
// }
// navigator.mediaDevices.getUserMedia(constraints)
// .then((stream) => {
// console.log('stream -> ', stream)
// })
// .catch((error) => {
// console.error('Some error occured while changing the camera view ', error)
// console.log(error)
// })
this.setState({ videoConstraints: tempVideoConstraint, activeVideoInputID: remainingVideoStreams[0].deviceId })
} else {
// show the remaining stream list to user
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
答案 0 :(得分:2)
这是您的实现的微小变化。 但这完全可以满足您的要求。
请参阅以下实现来前后切换相机。 我还添加了错误验证,例如:
如果您有任何其他方法或想要进一步说明,请喜欢并发表评论
componentDidMount() {
const gotDevices = (mediaDevices) =>
new Promise((resolve, reject) => {
const availableVideoInputs = []
mediaDevices.forEach(mediaDevice => {
if (mediaDevice.kind === 'videoinput') {
availableVideoInputs.push({
deviceId: mediaDevice.deviceId,
label: mediaDevice.label
})
}
})
if (availableVideoInputs.length > 0) {
resolve(availableVideoInputs)
} else {
reject(new Error('ERR::NO_MEDIA_TO_STREAM'))
}
})
navigator.mediaDevices.enumerateDevices().then(gotDevices)
.then((availableVideoInputs) => this.setState({ availableVideoInputs }))
.catch((err) => this.setState({ hasError: err }))
}
updateFileUploadView(newActiveView) {
this.setState({ activeFileUploadView: newActiveView })
const { hasError } = this.state
if (newActiveView === 'clickFromWebcam' && hasError) {
return console.error(hasError)
}
if (newActiveView === '') {
// means no view is active and clear the selected image
this.setState({ captureImageBase64: '', videoConstraints: defaultVideoConstraints })
}
}
changeCameraView() {
const { availableVideoInputs } = this.state
if (availableVideoInputs.length === 1) {
return console.error('ERR::AVAILABLE_MEDIA_STREAMS_IS_1')
}
this.setState({ resetCameraView: true })
setTimeout(() => {
const { videoConstraints: { facingMode } } = this.state
const newFacingMode = facingMode === 'user' ? { exact: 'environment' } : 'user'
this.setState({
videoConstraints: { facingMode: newFacingMode },
resetCameraView: false
})
}, 100)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
!resetCameraView ?
<Webcam
audio={false}
height='100%'
ref={this.webCamRef}
screenshotFormat="image/png"
minScreenshotWidth={screenShotWidth}
minScreenshotHeight={screenShotHeight}
screenshotQuality={1}
width='100%'
videoConstraints={videoConstraints}
/>
: 'Loading...'
如您所见,此实现使用的是反应网络摄像头库
在 componentDidMount 中,您将首先检查类型为视频输入的可用媒体流,然后在其他方法中(例如更改cameraView),即将摄像机切换为前/后。 / p>
我仅在100毫秒内卸载网络摄像头,然后使用新的 videoConstraints 将其重新安装回 {FaceingMode:'user'} 或< strong> {faceMode:{确切的:'环境'}}
这种方法将使您的代码有一个良好的开端,并且您可以在代码中玩转并玩得开心。 谢谢!