DEV Community

Cover image for 用 HTML 的 capture 屬性,開啟手機鏡頭進行拍照、錄影
Let's Write
Let's Write

Posted on • Updated on • Originally published at letswrite.tw

用 HTML 的 capture 屬性,開啟手機鏡頭進行拍照、錄影

本篇要解決的問題

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

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

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

製作出來的 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/*"/>
Enter fullscreen mode Exit fullscreen mode

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

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


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

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

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

轉圖片

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

<img id="Im_image">
Enter fullscreen mode Exit fullscreen mode
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]);
}
Enter fullscreen mode Exit fullscreen mode

轉影片

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

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

<video id="Im_video" controls="controls"></video>
Enter fullscreen mode Exit fullscreen mode
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;
  });
}
Enter fullscreen mode Exit fullscreen mode

關於客製 input file

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

一般的 input file 樣子

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

客製 input file

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

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


支援度、安全性

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

HTML capture 的支援度

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

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

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

Top comments (0)