Kini banyak browser yang dapat mengakses input video dan audio dari pengguna. Namun, bergantung pada browser, pengalaman ini mungkin menjadi pengalaman yang sepenuhnya dinamis dan inline, atau dapat didelegasikan ke aplikasi lain di perangkat pengguna.
Memulai dengan mudah dan bertahap
Hal termudah untuk dilakukan adalah cukup meminta file yang sudah direkam sebelumnya kepada pengguna. Lakukan hal ini dengan membuat elemen input file
sederhana dan menambahkan filter accept
yang menunjukkan bahwa kita hanya dapat menerima file video dan
atribut capture
yang menunjukkan bahwa kita ingin mendapatkannya langsung dari kamera.
<input type="file" accept="video/*" capture />
Metode ini berfungsi di semua platform. Di desktop, ini akan meminta pengguna untuk mengupload file dari
sistem file (mengabaikan atribut capture
). Pada Safari di iOS, aplikasi kamera akan terbuka, sehingga Anda dapat merekam video lalu mengirimkannya kembali ke halaman web. Di Android, hal ini akan memberikan pilihan kepada pengguna aplikasi mana yang akan digunakan untuk merekam video sebelum mengirimnya kembali ke halaman web.
Banyak perangkat seluler memiliki lebih dari satu kamera. Jika memiliki preferensi, Anda dapat menetapkan atribut capture
ke user
jika ingin kamera menghadap ke pengguna, atau environment
jika ingin
kamera menghadap ke luar.
<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />
Perhatikan bahwa ini hanyalah petunjuk - jika browser tidak mendukung opsi ini, atau jenis kamera yang Anda minta tidak tersedia, browser dapat memilih kamera lain.
Setelah pengguna selesai merekam dan kembali ke situs, Anda
harus memiliki data file. Anda bisa mendapatkan akses cepat dengan menambahkan peristiwa onchange
ke elemen input, lalu membaca properti files
objek peristiwa.
<input type="file" accept="video/*" capture="camera" id="recorder" />
<video id="player" controls></video>
<script>
var recorder = document.getElementById('recorder');
var player = document.getElementById('player');
recorder.addEventListener('change', function (e) {
var file = e.target.files[0];
// Do something with the video file.
player.src = URL.createObjectURL(file);
});
</script>
Setelah memiliki akses ke file tersebut, Anda dapat melakukan apa pun yang Anda inginkan pada file tersebut. Misalnya, Anda dapat:
- Melampirkannya langsung ke elemen
<video>
sehingga Anda dapat memutarnya - Download aplikasi ke perangkat pengguna
- Upload ke server dengan melampirkannya ke
XMLHttpRequest
- Gambar bingkai ke kanvas dan terapkan filter ke kanvas
Meskipun metode elemen input untuk mendapatkan akses ke data video sudah ada di mana-mana, metode ini adalah opsi yang paling tidak menarik. Kita benar-benar ingin mendapatkan akses ke kamera dan memberikan pengalaman yang baik langsung di halaman.
Mengakses kamera secara interaktif
Browser modern dapat terhubung langsung ke kamera, sehingga kita dapat menciptakan pengalaman yang terintegrasi sepenuhnya dengan halaman web dan pengguna tidak akan pernah meninggalkan browser.
Mendapatkan akses ke kamera
Kita dapat langsung mengakses kamera menggunakan API di spesifikasi WebRTC
yang disebut getUserMedia()
. getUserMedia()
akan meminta pengguna untuk
mengakses mikrofon dan kamera yang terhubung.
Jika berhasil, API akan menampilkan Stream
yang akan berisi data dari kamera atau
mikrofon, lalu kita dapat melampirkannya ke elemen <video>
, melampirkannya ke aliran WebRTC,
atau menyimpannya menggunakan MediaRecorder
API.
Untuk mendapatkan data dari kamera, kita cukup menetapkan video: true
dalam objek batasan
yang diteruskan ke getUserMedia()
API
<video id="player" controls></video>
<script>
var player = document.getElementById('player');
var handleSuccess = function (stream) {
player.srcObject = stream;
};
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then(handleSuccess);
</script>
Jika ingin memilih kamera tertentu, Anda dapat menghitung kamera yang tersedia terlebih dahulu.
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices = devices.filter((d) => d.kind === 'videoinput');
});
Kemudian, Anda dapat meneruskan ID perangkat yang ingin digunakan saat memanggil getUserMedia
.
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
deviceId: devices[0].deviceId,
},
});
Dengan sendirinya, ini tidak berguna. Yang bisa kita lakukan adalah mengambil data video dan memutarnya kembali.
Mengakses data mentah dari kamera
Untuk mengakses data video mentah dari kamera, Anda dapat menggambar setiap frame ke dalam <canvas>
dan
memanipulasi piksel secara langsung.
Untuk kanvas 2D, Anda dapat menggunakan metode konteks drawImage
untuk menggambar frame elemen <video>
saat ini ke dalam kanvas.
context.drawImage(myVideoElement, 0, 0);
Dengan kanvas WebGL, Anda dapat menggunakan elemen <video>
sebagai sumber tekstur.
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
myVideoElement,
);
Perlu diperhatikan bahwa dalam kedua kasus tersebut, frame saat ini dari video yang sedang diputar akan digunakan. Untuk memproses beberapa frame, Anda harus selalu menggambar ulang video ke kanvas.
Anda dapat mempelajari hal ini lebih lanjut dalam artikel kami tentang menerapkan efek real-time ke gambar dan video.
Menyimpan data dari kamera
Cara termudah untuk menyimpan data dari kamera adalah dengan menggunakan
MediaRecorder
API.
MediaRecorder
API akan mengambil aliran data yang dibuat oleh getUserMedia
, lalu secara progresif menyimpan data dari aliran data ke tujuan yang Anda inginkan.
<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
let shouldStop = false;
let stopped = false;
const downloadLink = document.getElementById('download');
const stopButton = document.getElementById('stop');
stopButton.addEventListener('click', function() {
shouldStop = true;
})
var handleSuccess = function(stream) {
const options = {mimeType: 'video/webm'};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
if(shouldStop === true && stopped === false) {
mediaRecorder.stop();
stopped = true;
}
});
mediaRecorder.addEventListener('stop', function() {
downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
downloadLink.download = 'acetest.webm';
});
mediaRecorder.start();
};
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(handleSuccess);
</script>
Dalam kasus ini, kita menyimpan data secara langsung ke dalam array yang nantinya dapat kita ubah menjadi Blob
yang kemudian dapat digunakan untuk disimpan ke Server Web atau langsung di penyimpanan di perangkat pengguna.
Minta izin untuk menggunakan kamera secara bertanggung jawab
Jika pengguna belum pernah memberikan situs Anda akses ke kamera,
begitu Anda memanggil getUserMedia
, browser akan meminta pengguna
memberikan izin ke kamera kepada situs Anda.
Pengguna tidak suka dimintai akses ke perangkat canggih di komputer mereka dan sering kali mereka memblokir permintaan tersebut, atau akan mengabaikannya jika tidak memahami konteks pembuatan perintah. Praktik terbaiknya adalah hanya meminta untuk mengakses kamera saat pertama kali diperlukan. Setelah pengguna memberikan akses, mereka tidak akan diminta lagi untuk melakukannya. Namun, jika pengguna menolak akses, Anda tidak akan dapat memperoleh akses lagi untuk meminta izin kepada pengguna tersebut.
Gunakan API izin untuk memeriksa apakah Anda sudah memiliki akses
getUserMedia
API tidak memberi tahu apakah Anda sudah
memiliki akses ke kamera. Hal ini menimbulkan masalah. Untuk memberikan UI yang bagus
agar pengguna memberi Anda akses ke kamera, Anda harus meminta
akses ke kamera.
Hal ini dapat diatasi di beberapa browser dengan menggunakan Permission API. API
navigator.permission
memungkinkan Anda membuat kueri status kemampuan untuk
mengakses API tertentu tanpa harus meminta izin lagi.
Untuk mengkueri apakah Anda memiliki akses ke kamera pengguna, Anda dapat meneruskan
{name: 'camera'}
ke dalam metode kueri dan metode ini akan menampilkan:
granted
— pengguna sebelumnya telah memberi Anda akses ke kamera;prompt
— pengguna belum memberi Anda akses dan akan diminta saat Anda memanggilgetUserMedia
;denied
— sistem atau pengguna telah secara eksplisit memblokir akses ke kamera dan Anda tidak akan bisa mendapatkan akses ke kamera.
Sekarang Anda dapat memeriksa dengan cepat untuk mengetahui apakah perlu mengubah antarmuka pengguna untuk mengakomodasi tindakan yang perlu dilakukan pengguna.
navigator.permissions.query({name: 'camera'}).then(function (result) {
if (result.state == 'granted') {
} else if (result.state == 'prompt') {
} else if (result.state == 'denied') {
}
result.onchange = function () {};
});