DEV Community

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

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

5

用 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 的當下,大家逛網站真的是不要亂點不信任的網站任何按鈕或連結,看到點了某個按鈕時突然打開了鏡頭時,更要當心。

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay