<%@ Page Title="Webcam capture" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Webcam capture - AjaxUploader v5.2 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Webcam capture (photo + video)</asp:Content>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">In-browser webcam source via <code>openWebcamCapture()</code></div> <div class="demo-card-body"> <p class="demo-description"> One call opens a modal that previews the user's webcam, lets them snap a JPEG (<code>mode: 'photo'</code>) or record a webm/mp4 clip (<code>mode: 'video'</code>), and resolves with a <code>File</code> ready to drop into the upload queue. No <code>&lt;input type="file"&gt;</code> round-trip, no third-party SDK, no server work.
 </p> <div class="demo-expect"><strong>What you should see:</strong> take a photo with the webcam straight into the queue; review before uploading, or pick from disk instead.</div> <div class="card p-3 mt-3" style="background:#fff;border:1px solid #e2e8f0;"> <div class="d-flex flex-wrap gap-2"> <button id="webcamPhotoBtn" type="button" class="btn btn-primary">Take a photo</button> <button id="webcamVideoBtn" type="button" class="btn btn-outline-primary">Record video (max 30s)</button> </div> <p class="mt-2 text-muted small mb-0">First click prompts for camera permission. Press <kbd>Esc</kbd> in the modal to cancel.</p> <div id="webcamCaptureStatus" class="form-text" aria-live="polite"></div> <div id="webcamUploader" class="mt-3"></div> </div> <script> (function () {
 function init() {
 if (!window.AjaxUploader || typeof AjaxUploader.create !== 'function') return;
 var uploader = AjaxUploader.create('#webcamUploader', {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 multiple: true,
 autoUpload: false
 });
 var photoButton = document.getElementById('webcamPhotoBtn');
 var videoButton = document.getElementById('webcamVideoBtn');
 var status = document.getElementById('webcamCaptureStatus');
 function showCaptureError(err) {
 if (err && err.message === 'cancelled') return;
 if (status) status.textContent =
 (err && err.message) || 'Webcam capture could not be started.';
 }
 function openCapture(options) {
 if (status) status.textContent = '';
 if (!uploader || typeof uploader.openWebcamCapture !== 'function') {
 showCaptureError(new Error('Webcam capture is not available in this browser.'));
 return;
 }
 uploader.openWebcamCapture(options)
 .then(function (file) {
 if (uploader && typeof uploader.addFile === 'function') uploader.addFile(file);
 })
 .catch(showCaptureError);
 }
 if (photoButton) photoButton.addEventListener('click', function () {
 openCapture({ mode: 'photo' });
 });
 if (videoButton) videoButton.addEventListener('click', function () {
 openCapture({ mode: 'video', audio: true, maxDurationSec: 30 });
 });
 }
 if (document.readyState !== 'loading') init();
 else document.addEventListener('DOMContentLoaded', init);
 })();
 </script> <div class="alert alert-info mt-3" role="alert"> <strong>Browser requirements:</strong> secure context (HTTPS or <code>localhost</code>) and user permission for the camera (and microphone in video mode). Falls back to a descriptive rejected promise if either is unavailable.
 </div> <h5 class="mt-4">JavaScript API</h5> <div class="code-panel">
<pre><code><span style="color:#94a3b8">// Photo mode (default) - resolves with image/jpeg.</span>
uploader.openWebcamCapture()
 .then(function (file) { uploader.addFile(file); });

<span style="color:#94a3b8">// Video mode with mic + 60-second cap.</span>
uploader.openWebcamCapture({
 mode: 'video',
 audio: true,
 maxDurationSec: 60,
 mimeType: 'video/webm;codecs=vp9,opus', <span style="color:#94a3b8">// optional</span> fileName: 'demo-clip.webm' <span style="color:#94a3b8">// optional</span>
}).then(function (file) { uploader.addFile(file); });</code></pre> </div> <h5 class="mt-4">What ships</h5> <ul class="mb-3"> <li>Modal overlay with live <code>&lt;video&gt;</code> preview, action buttons, and a status row that ticks the elapsed recording time.</li> <li>Format negotiation via <code>MediaRecorder.isTypeSupported</code> - picks the best WebM / MP4 codec the browser supports.</li> <li><kbd>Esc</kbd> cancels and rejects with <code>Error('cancelled')</code> - easy to filter out of error logs.</li> <li>All tracks stop automatically on close to release the camera light.</li> </ul> <h5 class="mt-4">Pair with the image editor</h5> <p>Webcam -> image editor -> upload is a single Promise chain:</p> <div class="code-panel">
<pre><code>uploader.openWebcamCapture({ mode: 'photo' })
 .then(function (file) { return uploader.openImageEditor(file, { aspectRatio: 1 }); })
 .then(function (edited) { uploader.addFile(edited); });</code></pre> </div> </div>
</div> 
</asp:Content>
