H5調用攝像頭拍照上傳


場景  h5點擊喚醒手機攝像頭,拍照並上傳到oss

 

方案選擇,在網上找了幾個案例做了幾個demo,首先是沒有直接可以用的插件(難受😣)

 

可選方案

1、getUserMedia API

 

getUserMedia API最初是navigator.getUserMedia,目前已被最新Web標准廢除,變更為navigator.mediaDevices.getUserMedia(),但瀏覽器支持情況不如舊版API普及。 

pc瀏覽器上沒有問題

demo 可以直接復制查看效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拍照</title>
</head>
<body>
<video id="video" width="640" height="480" autoplay="autoplay"></video>
<!--拍照按鈕-->
<div>
    <button id="capture">拍照</button>
</div>
<!--描繪video截圖-->
<canvas id="canvas" width="640" height="480"></canvas>
<script>
    let video = document.getElementById("video");
    let canvas = document.getElementById("canvas");
    let context = canvas.getContext("2d");

    // 老的瀏覽器可能根本沒有實現 mediaDevices,所以我們可以先設置一個空的對象
    if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
    }

    // 一些瀏覽器部分支持 mediaDevices。我們不能直接給對象設置 getUserMedia
    // 因為這樣可能會覆蓋已有的屬性。這里我們只會在沒有getUserMedia屬性的時候添加它。
    if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = function (constraints) {

            // 首先,如果有getUserMedia的話,就獲得它
            var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

            // 一些瀏覽器根本沒實現它 - 那么就返回一個error到promise的reject來保持一個統一的接口
            if (!getUserMedia) {
                return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
            }

            // 否則,為老的navigator.getUserMedia方法包裹一個Promise
            return new Promise(function (resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject);
            });
        }
    }

    //默認使用前攝像頭,強制使用后置攝像頭如下設置
    // let constraints = {video: { facingMode: { exact: "environment" } }};
    let constraints = {video: true};
    navigator.mediaDevices.getUserMedia(constraints)
        .then(function (stream) {
            // 舊的瀏覽器可能沒有srcObject
            if ("srcObject" in video) {
                video.srcObject = stream;
            } else {
                // 防止在新的瀏覽器里使用它,應為它已經不再支持了
                video.src = window.URL.createObjectURL(stream);
            }
            video.onloadedmetadata = function (e) {
                video.play();
            };
        })
        .catch(function (err) {
            console.log(err.name + ": " + err.message);
        });

    //注冊拍照按鈕的單擊事件
    document.getElementById("capture").addEventListener("click", function () {
        //繪制畫面
        context.drawImage(video, 0, 0, 640, 480);
    });
</script>
</body>
</html> 

不過在手機中打開歇菜

 

 所以這個方案行不通

 

2.原生input

 

使用input標簽 type值為file,可以調用系統默認的照相機、相冊、攝像機、錄音功能。

<input type="file" accept="image/" capture="camera">
<input type="file" accept="video/" capture="camcorder">
<input type="file" accept="audio/*" capture="microphone">

 

accept表示打開的系統文件目錄
capture表示的是系統所捕獲的默認設備,camera:照相機;camcorder:攝像機;microphone:錄音;
其中還有一個屬性multiple,支持多選,當支持多選時,multiple優先級高於capture,所以只用寫成:<input type="file" accept="image/*" multiple>就可.

還有就是希望做到默認打開前置攝像頭
需要設置 capture="user"  但是我寫demo一直調用不到前置攝像頭,我一直以為是我的使用姿勢不對。。。
后來發現這個其實是安卓不支持這個屬性,只有IOS支持的比較好(我暈。。。我用的安卓手機)
 
另外還有一個問題,就是我用的是react,在input中設置 capture屬性,但是在瀏覽器審查元素,這個屬性會丟失
 
所以在組件中
 
compomentDidMount里暴力塞進去
 
componentDidMount() {
    this.ifSetting()
    document.getElementsByClassName('select-video')[0].setAttribute('capture', 'user')
  }

 

完美~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM