本篇要解決的問題
以前研究過一下怎麼用 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/*"/>
想看效果的朋友可以進到 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 上放個不寫 src
的 video
,之後抓到 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"
,預設會長的像這樣:
但因為這邊我們讓使用者做的動作是「打開鏡頭」,如果顯示的像預設那樣是寫「選擇檔案」,使用者會感到疑惑,所以 Demo 上有客製了 input file 的樣子成一個按鈕,上面可以寫上我們想要的文字:
客製 input file 的方式本站以前有寫過,這邊就不再重複寫,有興趣的朋友可以點連結觀看:
File API 客製上傳檔案按鈕 / input file
支援度、安全性
HTML capture
這個 attribute 的支援度,在 Can I use 上是這樣:
可以看到支援的部份全在手機,這也正常,現在大家都手機不離身了,要拍照或錄影也不會用電腦來使用。
關於安全性,這邊要寫的並不是說用這個 HTML 的屬性安不安全,而是像參考連結裡第一篇文章提到的,用 capture
這個方式,並不會像用 App 那樣,會先詢問使用者能不能授權開啟相機功能,而是直接就打開了,這對使用者來說會有安全的疑慮。
但就像參考文章中說的,這最後的產出是一個 input 裡的檔案,當我們逛網頁時,如果自己點擊了 input,打開相機,又自己按下了拍照或錄影,然後又按下了確定使用照片或影片,這都是我們自己決定的,而且至少要 3 次的點擊才會把照片傳到網頁上,這中間的過程,目前只能說,在瀏覽器並未限制使用者點擊了帶有 capture
屬性的 input
的當下,大家逛網站真的是不要亂點不信任的網站任何按鈕或連結,看到點了某個按鈕時突然打開了鏡頭時,更要當心。
Top comments (0)