工作中總會遇到一些麻煩的問題,有問題不要怕解決就好了,前段時間要實現微信h5頁面人臉注冊/登錄,本以為很簡單的一個東西,沒想到居然這么麻煩,寫個文章記錄下過程和遇到的問題及解決辦法:
需求:①人臉注冊,需進行活體認證,用戶利用攝像頭拍攝一段視頻並朗讀生成的4位隨機數。
②人臉登陸:靜默登陸,打開攝像頭拍照並上傳,與底板進行對比。
① 最開始是想利用下面的打開攝像頭
navigator.mediaDevices.getUserMedia
然后利用下面的去捕獲媒體流
var mediaRecorder = new MediaRecorder(stream,{ mimeType:'video/webm;codecs=h264' });
再把捕獲的媒體流通過表單進行上傳
var file = new File([recorderFile], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.mp4', { type: 'video/mp4' }); var data = new FormData(); data.append("username", "test"); data.append("file", file);
最后發現上傳和下載下來的視頻都沒有畫面,不管怎么調編碼,就是這個mimeType:'video/webm;codecs=h264',都是只有聲音沒有畫面,沒辦法就換了另外一個想法,牛掰的input,利用input去調用本地攝像機,錄制完成后通過onchange事件實現自動上傳視頻,這樣就解決了沒有畫面的問題,而且蘋果和安卓都是兼容的,代碼如下:
HTML
<form id="modify2" name="getForm" enctype="multipart/form-data" method="post"> <input type="file" name="video" accept="video/*" capture="user" class="openCamera" onchange="openCamera()"/> </form>
JS
function openCamera(){ const formDate = new FormData($("#modify")[0]) formDate.append("username",username) $.ajax({ type:"post", url:"urlXXX", data:formDate, mimeType:"multipart/form-data", contentType:false, cache:false, processData:false, success:function(data){ console.log(data) }, error:function(res){ console.log(res) } }); }
這樣就實現了活體驗證,進行了人臉注冊。
②在做這個時候也是用了getUserMedia這個方法,然后在用canvas進行截圖,最后上傳,代碼如下:
HTML
<div class="videoJt"> <video width='115' height='150' autoplay muted id="video" webkit-playsinline='true' playsinline='true'></video> <canvas id="canva" width='150' height='150'></canvas> </div>
JS
function start(){ function $$(elem) { return document.querySelector(elem); } var canvas = $$('#canva'), context = canvas.getContext('2d'), video = $$('#video') //打開攝像頭 navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || window.getUserMedia; var constraints = {video: true, audio: false}; if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { video.srcObject = stream // video.play() setTimeout(function(){ screenshot() },6000) }).catch(function(err) { console.log(err); }) }else if (navigator.getUserMedia) { navigator.getUserMedia(constraints, function (stream) { video.srcObject = stream; setTimeout(function(){ screenshot() },6000) }, function (err) { callback(err); }); } else { console.log(new Error('Not support userMedia')); } // 截取圖像 function screenshot(){ context.drawImage(video, 0, 0, 115, 150); let base64Data = canvas.toDataURL('image/png'); let blob = dataURItoBlob(base64Data); let fd = new FormData(); fd.append('image_best',blob); fd.append('username',username); closeMedia(); upload(fd); } // 關閉攝像頭 function closeMedia(videoElem){ let stream = video.srcObject; let tracks = stream.getTracks(); tracks.forEach(function(track){ track.stop(); }) video.srcObject = null; } //base64轉圖片 function dataURItoBlob (base64Data) { var byteString; if (base64Data.split(',')[0].indexOf('base64') >= 0) byteString = atob(base64Data.split(',')[1]); else byteString = unescape(base64Data.split(',')[1]); var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]; var ia = new Uint8Array(byteString.length); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], {type: mimeString}); }; // 上傳截取的圖像 function upload(data1) { $.ajax({ type:"post", url:"urlXXX", data:data1, dataType:"JSON", mimeType:"multipart/form-data", contentType:false, cache:false, processData:false, success:function(json){ console.log(json); }, error:function(res){ console.log(res); } }); } }()
本以為這樣就OK了,本人是安卓機測試是好的,就興沖沖的在蘋果上測,居然沒有反應,原來是ios的微信中是沒有getUserMedia的,沒辦法想出在進入這里的時候判斷是不是ios的微信,是那就提示利用外部瀏覽器打開,這樣也很麻煩,對蘋果用戶不是很友好,每次用人臉登陸都要跳出去很麻煩,因為是公眾號的H5,所以想到利用微信的jssdk,按照微信公眾平台的方法,引用了jssdk,看了api,有一個是創建相機wx.createCameraContext,但是在打印的時候報錯,createCameraContext not a function,一看是沒有,就選擇了chooseImage,提示沒有權限,又配置了wx.config才好用,調用起來之后和需求不太一樣,不是靜默的,於是就想到了一個迂回的辦法:
利用小程序,如圖:
通過公眾號點擊打開小程序,這時小程序去請求后台服務,判斷是否需要人臉登陸,不需要直接把返回的url直接填入web-view打開h5頁面即可,需要就通過小程序調用wx.createCameraContext進行靜默拍照並上傳,后端服務記錄一次當前是登陸人的信息,成功后用web-view打開h5頁面,在h5頁面向后端服務做請求,通過用戶信息對比是否同一個人,成功並返回登陸信息,進行頁面渲染,進入到功能頁面。
這樣就實現了在微信的整個人臉注冊/登陸的流程,比較繞,也比較笨,沒有找到更好的辦法只能先這么做,等想到更好的辦法的時候再替換,若有小伙伴也是同樣的需求,並且有更好的解決方法,請留言,或發郵箱544785380@qq.com,感激不盡,寫的不好,也有瑕疵,僅作為一次經驗參考,有不對的地方希望小伙伴們能批評指出,我及時改正。
每一個努力的人都值得被肯定,但是最大的肯定來源於自己!!!
加油每一天!!!
附加:不知道js怎么錄制視頻的小伙伴可以參考:https://blog.csdn.net/mrzhangdulin/article/details/84560146