添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本篇要解決的問題

以前研究過一下怎麼用 JavaScript 打開手機的鏡頭,進行拍照或錄影,當時做出了 Demo 後,然後就……突然一陣子忙,就忘記寫文章了 XD。

直到昨天看到一篇文章,才知道原來 HTML 本身就有 attribute 讓使用者開啟鏡頭,進行拍照或錄影,而且寫起來 Hen~ 簡單,就決定製作一個小 Demo,並寫出這篇筆記文。

參考的文章及 MDN 的說明連結在這:

  • You Can Access A User’s Camera with Just HTML
  • HTML attribute: capture
  • 製作出來的 Demo 在這,只能用手機操作,用桌機的話無法使用。

    https://letswritetw.github.io/letswrite-html-capture/

    HTML 屬性開啟鏡頭

    這邊直接提供開啟手機鏡頭的 HTML 屬性是什麼:

  • capture: user 前鏡頭、 environment 後鏡頭
  • accept: audio 聲音檔、 video 影片檔、 image 圖檔
  • 這二個屬性是寫在 input type="file" 裡的,範例如下:

    <!-- 開啟 前鏡頭 錄影、拍照 -->
    <input type="file" capture="user" accept="video/*"/>
    <input type="file" capture="user" accept="image/*"/>
    <!-- 開啟 後鏡頭 錄影、拍照 -->
    <input type="file" capture="environment" accept="video/*"/>
    <input type="file" capture="environment" accept="image/*"/>

    想看效果的朋友可以進到 Demo 裡去玩一玩,Demo 頁不會把大家的照片或影片給存下來,一切都是在頁面上操作而已 (因為沒有酷錢錢買空間存)

    另外,August 用 iPhone 實測時,前鏡頭預設會打開閃光燈,拍照前記得關掉,不然會被閃到看見人生的跑馬燈。

    把使用者照片、影片放到頁面上預覽

    在 Demo 頁上如果大家有試玩拍照跟錄影,會看見 August 有把拍照的照片跟錄影的影片給放在結果顯示區,這個不用擔心,並不是先存到某台主機上後,再把路徑丟回給頁面,而是直接用 FileReader 把各位當下的檔案給塞到頁面上 img video src 裡。

    這段是要寫怎麼把照片、影片給轉成網頁可讀的 src (買不起空間啊廣告還不點起來讓本站賺個微簿的酷錢錢)

    最簡單的方式,先在 HTML 上放個不寫 src img ,之後抓到 Base64 後再寫進 src 裡。

    <img id="Im_image">
    const input = document.getElementById('xxx');
    input1.addEventListener('change', handleFilesImage, false);
    function handleFilesImage() {
      const fileData = this.files;
      const reader = new FileReader();
      reader.addEventListener('load', file => {
        const img = document.getElementById('Im_image');
        img.src = file.target.result;
      reader.readAsDataURL(fileData[0]);
    

    一樣用最簡單的方式,先在 HTML 上放個不寫 srcvideo,之後抓到 Blob 後再寫進 src 裡。

    轉影片的 JavaScript 主要參考這篇:How to read large video files in JavaScript using FileReader?

    <video id="Im_video" controls="controls"></video>
    const input = document.getElementById('xxx');
    input1.addEventListener('change', handleFilesVideo, false);
    function handleFilesVideo() {
      const fileData = this.files;
      const reader = new FileReader();
      reader.readAsArrayBuffer(fileData[0]);
      reader.addEventListener('load', file => {
        const buffer = file.target.result;
        const videoBlob = new Blob([new Uint8Array(buffer)], { type: 'video/mp4' });
        const url = window.URL.createObjectURL(videoBlob);
        const video = document.getElementById('Im_video');
        video.src = url;
    

    關於客製 input file

    如果直接用 input type="file",預設會長的像這樣:

    一般的 input file 樣子
    一般的 input file 樣子

    但因為這邊我們讓使用者做的動作是「打開鏡頭」,如果顯示的像預設那樣是寫「選擇檔案」,使用者會感到疑惑,所以 Demo 上有客製了 input file 的樣子成一個按鈕,上面可以寫上我們想要的文字:

    客製 input file
    客製 input file

    客製 input file 的方式本站以前有寫過,這邊就不再重複寫,有興趣的朋友可以點連結觀看:

    File API 客製上傳檔案按鈕 / input file

    支援度、安全性

    HTML capture 這個 attribute 的支援度,在 Can I use 上是這樣:

    HTML capture 的支援度
    HTML capture 的支援度

    可以看到支援的部份全在手機,這也正常,現在大家都手機不離身了,要拍照或錄影也不會用電腦來使用。

    關於安全性,這邊要寫的並不是說用這個 HTML 的屬性安不安全,而是像參考連結裡第一篇文章提到的,用 capture 這個方式,並不會像用 App 那樣,會先詢問使用者能不能授權開啟相機功能,而是直接就打開了,這對使用者來說會有安全的疑慮。

    但就像參考文章中說的,這最後的產出是一個 input 裡的檔案,當我們逛網頁時,如果自己點擊了 input,打開相機,又自己按下了拍照或錄影,然後又按下了確定使用照片或影片,這都是我們自己決定的,而且至少要 3 次的點擊才會把照片傳到網頁上,這中間的過程,目前只能說,在瀏覽器並未限制使用者點擊了帶有 capture 屬性的 input 的當下,大家逛網站真的是不要亂點不信任的網站任何按鈕或連結,看到點了某個按鈕時突然打開了鏡頭時,更要當心。

    Summary
    用 HTML 的 capture 屬性,開啟手機鏡頭進行拍照、錄影
    Article Name
    用 HTML 的 capture 屬性,開啟手機鏡頭進行拍照、錄影
    Description
    探索如何使用 HTML 的 capture 屬性開啟手機鏡頭進行拍照和錄影。本文詳細解釋了開啟鏡頭、預覽照片和影片、轉圖片和轉影片的方法,以及客製 input file 和支援度和安全性的考慮。附帶實用範例和說明。
    Augustus