Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Combinando y grabando ⏺ video 🎥 y audio 🎙 en el...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Lupo Montero
February 28, 2019
Programming
34
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Combinando y grabando ⏺ video 🎥 y audio 🎙 en el navegador
Mozilla Perú 28 Feb 2019
Lupo Montero
February 28, 2019
More Decks by Lupo Montero
See All by Lupo Montero
Trigonometría Bella
lupomontero
0
45
Analizadores sintácticos funcionales en JavaScript
lupomontero
0
100
Manejo de memoria en Rust: Ownership
lupomontero
0
48
Hola Rust! Aprendiendo con rustlings
lupomontero
1
330
WebThing: construyamos una lámpara 💡
lupomontero
1
93
Reduzco, reuso y reciclo
lupomontero
0
45
Web Assembly, Rust y el futuro de JavaScript
lupomontero
0
59
Primeros pasos con Rust y WebAssembly
lupomontero
0
550
Paralelizando promesas
lupomontero
0
360
Other Decks in Programming
See All in Programming
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
dRuby over BLE
makicamel
2
390
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
300
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
600
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
100
act1-costs.pdf
sumedhbala
0
120
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.3k
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
620
AIを活用したE2Eテスト実装効率化のあゆみ / ebisu-mobile-14-kotetu
kotetuco
0
130
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
230
さぁV100、メモリをお食べ・・・
nilpe
0
160
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.5k
Featured
See All Featured
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
260
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
150
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
450
Code Reviewing Like a Champion
maltzj
528
40k
A designer walks into a library…
pauljervisheath
211
24k
Transcript
Combinando y grabando ⏺ video 🎥 y audio 🎙 en
el navegador @lupomontero - Mozilla Perú 28 Feb 2019
@Laboratoriala @LimaJSorg @NodeSchool @lupomontero @mozillaperu
WTF @!#$!! https://support.useloom.com/faqs-and-troubleshooting/general-faq/can-i-use-loo m-with-firefox-safari-etc
Estándares al rescate • MediaDevices • MediaStream • <video> •
<canvas> • Blob • ...
navigator.mediaDevices.getUserMedia navigator.mediaDevices.getUserMedia({ camera: { video: true }, }) .then((stream) =>
{ // `stream` is a `MediaStream` }) .catch(console.error);
MediaStream const track = stream.getVideoTracks()[0]; console.log(track.getSettings());
<video> const streamSettings = stream.getVideoTracks()[0].getSettings(); const video = document.createElement('video'); video.setAttribute('width',
streamSettings.width); video.setAttribute('height', streamSettings.height); video.srcObject = stream; video.play();
<canvas> const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); ctx.drawImage(
image, dx, dy, dWidth, dHeight, ); https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
<canvas> const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); ctx.drawImage(
video, dx, dy, dWidth, dHeight, ); https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
canvas.captureStream() const outputStream = new MediaStream(); const inputStreams = [audioStream,
canvas.captureStream()]; inputStreams.forEach( stream => stream.getTracks().forEach( track => outputStream.addTrack(track), ), );
window.requestAnimationFrame const update = () => { // redraw frame
... window.requestAnimationFrame(update); }; update();
MediaRecorder const recordedBlobs = []; const recorder = new MediaRecorder(outputStream,
{ mimeType: 'video/webm', }); recorder.addEventListener('dataavailable', (e) => { if (e.data && e.data.size > 0) { recordedBlobs.push(e.data); } }); recorder.start(1000);
Blob y window.URL recorder.stop(); const blob = new Blob(recordedBlobs, {
type: 'video/webm' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = 'test.webm'; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 100);
Demo time!!!