< template> < div style= "height: 100vh;background: #000;" > < span style= "color: #fff;font-size: 18px;" > 切换数量:{ { devices. length } } < / span> < video ref= "video" autoplay muted playsinline> < / video> < div class = "video_btn" > < van- button round @click= "start" type= "info" > { { isRecording ? ` ${ timernum} 秒后停止录制 ` : '开始录制' } } < / van- button> < van- button round @click= "switchCamera" : disabled= "isRecording" > 切换摄像头< / van- button> < / div> < video v- if = "recordedVideoUrl" : src= "recordedVideoUrl" controls> < / video> < / div>
< / template> < script>
export default { data ( ) { return { mediaStream : null , mediaRecorder : null , recordedChunks : [ ] , recordedVideoUrl : null , isRecording : false , currentDeviceId : null , currentText : true , devices : [ ] , timer : null , timernum : 30 , maxFileSize : 100 * 1024 * 1024 , } } , mounted ( ) { this . startCamera ( ) } , methods : { async startCamera ( ) { try { const devices = await navigator. mediaDevices. enumerateDevices ( ) this . devices = devices. filter ( device => device. kind === "videoinput" ) if ( this . devices. length === 0 ) { throw new Error ( "没有找到摄像头设备" ) } this . currentDeviceId = this . devices[ 0 ] . deviceIdthis . mediaStream = await navigator. mediaDevices. getUserMedia ( { video : { deviceId : this . currentDeviceId } } ) const videoElement = this . $refs. videovideoElement. srcObject = this . mediaStream} catch ( error) { console. error ( "无法访问摄像头:" , error) } } , start ( ) { if ( this . isRecording) { this . stopRecording ( ) } else { this . startRecording ( ) } } , startRecording ( ) { if ( this . mediaStream) { this . mediaRecorder = new MediaRecorder ( this . mediaStream) this . recordedChunks = [ ] this . mediaRecorder. ondataavailable = ( event ) => { if ( event. data. size > 0 ) { this . recordedChunks. push ( event. data) const totalSize = this . recordedChunks. reduce ( ( acc, chunk ) => acc + chunk. size, 0 ) if ( totalSize > this . maxFileSize) { this . stopRecording ( ) } } } this . mediaRecorder. onstop = ( ) => { const blob = new Blob ( this . recordedChunks, { type : "video/webm" } ) this . recordedVideoUrl = URL . createObjectURL ( blob) } this . timer = setInterval ( ( ) => { this . settime ( ) } , 1000 ) this . mediaRecorder. start ( ) this . isRecording = true } } , settime ( ) { if ( this . timernum < 1 ) { this . stopRecording ( ) clearInterval ( this . timer) return } else { this . timernum-- } } , stopRecording ( ) { if ( this . mediaRecorder) { this . mediaRecorder. stop ( ) clearInterval ( this . timer) this . isRecording = false } this . timernum = 30 } , async switchCamera ( ) { try { this . stopStream ( ) const devices = await navigator. mediaDevices. enumerateDevices ( ) this . devices = devices. filter ( device => device. kind === "videoinput" ) let currentIndex = 0 if ( this . devices. length == 2 ) { currentIndex = this . devices. findIndex ( device => device. deviceId === this . currentDeviceId) const nextIndex = ( currentIndex + 1 ) % this . devices. lengththis . currentDeviceId = this . devices[ nextIndex] . deviceId} else if ( this . devices. length > 2 ) { if ( this . currentText) { this . currentDeviceId = this . devices[ 1 ] . deviceIdthis . currentText = false } else { this . currentDeviceId = this . devices[ 0 ] . deviceIdthis . currentText = true } } this . mediaStream = await navigator. mediaDevices. getUserMedia ( { video : { deviceId : this . currentDeviceId } } ) const videoElement = this . $refs. videovideoElement. srcObject = this . mediaStream} catch ( error) { this . $toast ( '无法切换摄像头' + error) } } , stopStream ( ) { if ( this . mediaStream) { const tracks = this . mediaStream. getTracks ( ) tracks. forEach ( track => track. stop ( ) ) } } }
}
< / script> < style>
. video_btn { position : fixed; bottom : 30px; z- index: 99 ; display : flex; justify- content: space- around; align- items: center; width : 100 % ; max- width: 640px; margin : 0 auto;
} video { width : 100 % ; height : 80vh; max- width: 640px; margin : 0 auto;
}
< / style>