Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Media Capture API: acquisire audio, video e immagini

Link copiato negli appunti

Per far interagire una Windows Store App con perferiche multimediali come webcam e microfono, abbiamo a disposizione due serie di API, rappresentate da due classi:

  • la classe CameraCaptureUI, che ci permette di sfruttare l'interazione con webcam e microfoni prevista dall'interfaccia utente standard messa a disposizione da WinRT, lasciando al sistema il compito di provvedere ai dettagli e assicurando al contempo agli utenti una user experience coerente con "l'ecosistema" di Windows 8;
  • la classe MediaCapture, che ci permette di avere maggior controllo sulle operazioni di cattura audio e video, consentendoci ad esempio di applicare filtri e altri effetti speciali, o di per offrire agli utenti un'interfaccia utente personalizzata.

Come per le altre API di WinRT, anche in questo caso Visual Studio provvede automaticamente a referenziare le librerie necessarie al momento della creazione del nuovo progetto.

Sfruttare la classe CameraCaptureUI

La prima opzione è quella di usare la classe CameraCaptureUI, che permette di utilizzare la user interface standard offerta dalle API di WinRT; si tratta di un elemento da non sottovalutare, sia perché fornisce user interface in linea con lo stile di Windows 8, sia perché l'API è identica a prescindere dal linguaggio di sviluppo prescelto (C#/VB, C++, HTML5/JavaScript).

Per testare il codice degli esempi che faremo, si può usare il seguente codice HTML per la pagina principale della app (default.html); la pagina contiene un pulsante che attiva l'interfaccia standard della webcam e cattura una foto, e un div che mostra il risultato finale.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>Demo.Html.t.MediaCapture.JS</title>
	<!-- WinJS references -->
	<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
	<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
	<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
	<!-- Demo.Html.t.MediaCapture.JS references -->
	<link href="/css/default.css" rel="stylesheet" />
	<script src="/js/default.js"></script>
</head>
<body>
<button id="btnTakePicture">Take Photo</button>
<div>
	<div id="photoMessage" />
</div>
</body>
</html>

Il prossimo snippet mostra il codice JavaScript che viene eseguito alla pressione del pulsante:

app.onloaded = function () {    
	btnTakePicture.addEventListener("click", takePicture_click);
}
function takePicture_click(args) {
	var captureUI = new Windows.Media.Capture.CameraCaptureUI();
	captureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo)
		.done(function (capturedItem) {
			if (capturedItem) {
				photoMessage.innerHTML = "Immagine catturata.";
			}
			else {
				photoMessage.innerHTML = "Operazione cancellata dall'utente."
			}
		}, function (err) {
			photoMessage.innerHTML = "Qualcosa è andato storto.";
		});
}

Nell'handler dell'evento di click del pulsante, il codice crea un nuovo oggetto di tipo CameraCaptureUI, appunto la classe che gestisce la cattura di foto e video.

Subito dopo viene invocato il metodo CaptureFileAsync che, in modalità asincrona, cattura lo stream proveniente dalla webcam. Come tale, si evita di "congelare" la user interface non appena l'utente attiva la webcam. Questo metodo accetta come parametro un oggetto di tipo CameraCaptureUIMode, tramite il quale è possibile specificare che cosa "catturare": una foto (come nell'esempio appena proposto), un video o entrambi.

Il metodo CaptureFileAsync restituisce una promise che viene gestita dalla funzione done. La promise riceve un oggetto di tipo Windows.Storage.StorageFile che rappresenta l'immagine catturata dalla webcam.

Per visualizzare l'immagine presa dalla webcam, possiamo utilizzare il tradizionale tag HTML <img>, come mostrato nel prossimo snippet:

<body>
<button id="btnTakePicture">Take Photo</button>
<div>
	<imgid="photo"src="images/placeholder.png"/>
	<div id="photoMessage" />
</div>
</body>

Lo stream, rappresentato dall'oggetto StorageFile, può essere aperto con il metodo OpenAsync, che restituisce l'istanza di un oggetto che implementa l'interfaccia IRandomAccessStream, che a sua volta viene poi assegnato a una variabile.

Tramite il metodo createObjectURL l'oggetto viene quindi "associato" a una URL specifica e il risultato assegnato direttamente alla proprietà src del tag img:

function takePicture_click(args) {
	var captureUI = new Windows.Media.Capture.CameraCaptureUI();
	captureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo)
		.done(function (capturedItem) {
			if (capturedItem) {
				var objectUrl = URL.createObjectURL(capturedItem, { oneTimeOnly: true });
				document.getElementById("photo").src = objectUrl;
				photoMessage.innerHTML = "Immagine catturata."
			} else {
				photoMessage.innerHTML = "Operazione cancellata dall'utente."
			}
		}, function (err) {
			photoMessage.innerHTML = "Qualcosa è andato storto.";
		});
}

Se a questo punto eseguiamo l'applicazione e clicchiamo sul pulsante, anziché vedere la webcam attivarsi e l'immagine apparire sullo schermo, apparirà solo il messaggio "This app needs permission to use your camera. You can change this in the app's settings", mostrato nella prossima immagine:

La ragione di questo messaggio è semplice: non è possibile usare l'API della webcam senza aver prima dichiarato la relativa "capability" nell'application manifest. Questo messaggio è parte della UI standard ed è formulato in accordo alla lingua dell'utente.

Dichiariamo dunque la capability "Webcam" nell'application manifest, come mostrato nella seguente immagine (la capability "Internet (Client)" è aggiunta di default da Visual Studio a ogni nuovo progetto).

Adesso possiamo eseguire nuovamente l'applicazione. La prima volta che questa viene lanciata, WinRT mostrerà un dialog box per richiedere il permesso dell'utente per l'utilizzo della webcam:

Se l'utente nega il proprio permesso, la webcam non potrà essere usata. In questo caso, l'interfaccia utente verrà chiusa e il valore restituito dal metodo CaptureFileAsync sarà null. Il sistema ricorda la scelta dell'utente: per cambiare il permesso, l'utente dovrà attivare la Charms bar e selezionare il charm Settings e quindi Permissions, come illustrato nella prossima immagine.

Nel momento in cui lo switch viene impostato su On, l'applicazione riceve il permesso di usare la webcam e, a questo punto, è possibile procedere con la cattura. Impostando lo switch su Off, invece, l'accesso alla webcam verrà immediatamente interrotto.

La classe CameraCaptureUI permette di definire alcune impostazioni iniziali da usare per la cattura tramite le due proprietà VideoSettings e PhotoSettings. Ad esempio, il seguente codice permette di ritagliare ("crop") l'immagine (tramite la proprietà AllowCropping) e di definirne la ratio (tramite la proprietà CroppedAspectRatio), di impostare il formato dell'immagine a Jpeg (tramite la proprietà Format) e la risoluzione alla massima possibile (tramite la proprietà MaxResolution):

function takePicture_click(args) {
	var captureUI = new Windows.Media.Capture.CameraCaptureUI();
	captureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
	captureUI.photoSettings.croppedAspectRatio = { width: 4, height: 3 };
	captureUI.photoSettings.allowCropping = true;
	captureUI.photoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxPhotoResolution.highestAvailable;
	captureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo)
		.done(function (capturedItem) {
			if (capturedItem) {
				var objectUrl = URL.createObjectURL(capturedItem, { oneTimeOnly: true });
				document.getElementById("photo").src = objectUrl;
				photoMessage.innerHTML = "Immagine catturata.";
			} else {
				photoMessage.innerHTML = "Operazione cancellata dall'utente."
			}
		}, function (err) {
			photoMessage.innerHTML = "Qualcosa è andato storto.";
		});
}

Per registrare un video tramite l'interfaccia utente standard, il procedimento è sostanzialmente identico. La differenza è che, in questo caso, il parametro da passare al metodo CaptureFileAsync è rappresentato dall'enum CameraCaptureUIMode.Video, come mostrato nel seguente snippet:

captureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.video).done();

È anche possibile impostare il parametro a CameraCaptureUIMode.PhotoOrVideo per lasciare l'utente libero di decidere fra i due tipi di cattura.

La cattura video può essere configurata tramite la proprietà VideoSettings della classe CameraCaptureUI, come mostrato qui di seguito:

captureUI.videoSettings.allowTrimming = true;
captureUI.videoSettings.format = Windows.Media.Capture.CameraCaptureUIVideoFormat.mp4;
captureUI.videoSettings.maxDurationInSeconds = 30;
captureUI.videoSettings.maxResolution = Windows.Media.Capture.CameraCaptureUIMaxVideoResolution.highDefinition;

Se vogliamo registrare anche l'audio, dobbiamo ricordare di aggiungere la "capability" Microphone nell'application manifest.

Catturare foto, audio e video con la classe MediaCapture

Come abbiamo già accennato, a volte abbiamo bisogno di maggiore controllo sulle operazioni di cattura, o può capitare di dover realizzare una user interface personalizzata per la nostra app, diversa da quella standard. In casi come questi, possiamo sfruttare la classe MediaCapture.

Per poter eseguire il codice degli esempi che vedremo, è necessario aggiungere un paio di dichiarazioni all'application manifest. Dal momento che l'app ha intenzione di accedere sia alla webcam che al microfono, aggiungiamo le corrispondenti "capability" Webcam e Microphone nel file Package.appxmanifest. Inoltre, poiché che il codice salva il video nella cartella Videos dell'utente, aggiungiamo anche la capability "Videos Library".

Il seguente listato illustra un semplice esempio di utilizzo della classe MediaCapture che mostra a video lo stream proveniente dalla webcam e dal microfono.

app.onloaded = function ()
{
	btnStartDevice.addEventListener("click", startDevice_click);
}
var mediaCapture;
function startDevice_click(args)
{
	mediaCapture = new Windows.Media.Capture.MediaCapture();
	mediaCapture.onrecordlimitationexceeded = recordLimitationExceeded;
	mediaCapture.onfailed = mediaFailed;
	mediaCapture.initializeAsync()
		.done(null, function (err) {
			errorMessage.innerHTML = "Inizializzazione fallita. Controlla i permessi per la webcam";
		});
}
function recordLimitationExceeded(args) {
	errorMessage.innerHTML = "Superati i limiti di registrazione!";
}
function mediaFailed(args) {
	errorMessage.innerHTML = "Operazione fallita!";
}

È importante sottolineare che, quando l'evento RecordLimitationExceeded viene sollevato, l'app deve finalizzare il file in corso di registrazione tramite il metodo StopRecordingAsync.

Quindi il codice invoca il metodo InitializeAsync della classe MediaCapture per inizializzare la periferica. La prima volta che l'app viene eseguita, la chiamata al metodo InitializeAsync mostra un dialog per richiedere all'utente il permesso di utilizzare la periferica di cattura (per questa ragione, il metodo InitializeAsync dovrebbe essere chiamato dal thread della UI). In questo caso, e a differenza di quanto avviene con la classe CameraCaptureUI, se l'utente nega il permesso viene sollevata un'eccezione di tipo UnauthorizedAccessException.

Dopo che la periferica è stata correttamente inizializzata, possiamo iniziare a ricevere lo stream dalla webcam, come mostrato nel prossimo snippet:

app.onloaded = function () {
	btnStartDevice.addEventListener("click", startDevice_click);
	btnStartPreview.addEventListener("click", startPreview_click);
}
// ( ... )
function startPreview_click(args)
{
	try {
		previewVideo.src = URL.createObjectURL(mediaCapture, { oneTimeOnly: true });
		previewVideo.play();
	} catch (e) {
		// gestire l'errore
	}
}

Nell'event handler startPreview_click il codice imposta la proprietà src dell'elemento video in modo che questo punti all'oggetto MediaCapture corrente, quindi avvia la preview del video tramite il metodo play. A questo punto, l'app visualizzerà lo stream proveniente dalla webcam, come illustrato nella prossima figura.

Un'altra cosa che vale la pena di notare è la possibilità di aggiungere effetti audio e video allo stream tramite il metodo AddEffectAsync, come mostrato nel prossimo snippet:

function startPreview_click(args) {
	try {
		mediaCapture.addEffectAsync(Windows.Media.Capture.MediaStreamType.videoRecord, Windows.Media.VideoEffects.videoStabilization, null)
			.done(null, function (err) {
				// gestire l'errore
			});
		previewVideo.src = URL.createObjectURL(mediaCapture, { oneTimeOnly: true });
		previewVideo.play();
	} catch (e) {
		// gestire l'errore
	}
}

In questo esempio, il metodo AddEffectAsync viene utilizzato per applicare un semplice effetto di stabilizzazione dello stream proveniente dalla webcam. Questo metodo accetta tre parametri:

  • il primo parametro è rappresentato da un oggetto di tipo MediaStreamType, tramite il quale è possibile specificare il tipo di stream al quale l'effetto deve essere applicato (foto, audio, preview video o registrazione video);
  • il secondo parametro è dato da una stringa che rappresenta l'identificativo dell'effetto, ossia della classe che contiene gli algoritmi da applicare allo stream audio/video;
  • il terzo parametro è rappresentato da un dictionary che implementa l'interfaccia IPropertySet (per il momento un'interfaccia vuota, aperta a future implementazioni) e contenente i parametri di configurazione dell'effetto.

Nell'esempio proposto, per recuperare l'Id dell'effetto video il codice sfrutta la proprietà VideoStabilization (per il momento, l'unica disponibile) della classe VideoEffects, che restituisce una stringa con l'id corrispondente. Per rimuovere l'effetto dallo stream, è sufficiente invocare il metodo ClearEffectsAsync.

Il passo successivo è rappresentato dalla cattura di una foto dalla webcam. Il prossimo listato mostra un semplice esempio:

app.onloaded = function () {
	btnStartDevice.addEventListener("click", startDevice_click);
	btnStartPreview.addEventListener("click", startPreview_click);
	btnTakePhoto.addEventListener("click", takePicture_click);
}
// ...
function takePicture_click(args) {
	try {
		var photoStorage;
		Windows.Storage.KnownFolders.picturesLibrary.createFileAsync("snapshot", Windows.Storage.CreationCollisionOption.generateUniqueName)
			.then(function (newFile) {
				var photoStorage = newFile;
				var photoProperties = Windows.Media.MediaProperties.ImageEncodingProperties.createJpeg();
				return mediaCapture.capturePhotoToStorageFileAsync(photoProperties, photoStorage);
			})
			.done(function (result) {
				var url = URL.createObjectURL(photoStorage, { oneTimeOnly: true });
				photoImage.src = url;
			}, function (error) {
				errorMessage.innerText = "Errore nel salvare la foto";
			});
	} catch (e) {
		errorMessage.innerText = "Errore durante le operazioni di cattura";
	}
}

Il codice utilizza il metodo CapturePhotoToStorageAsync per salvare la foto come storage file. La prossima immagine mostra il risultato della cattura:

La classe MediaCapture espone anche un overload del metodo InitializeAsync che accetta un oggetto di tipo MediaCaptureInitializationSettings, che come suggerito dal nome, contiene le impostazioni di inizializzazione della periferica. Grazie ad esso ad esempio, è possibile:

  • scegliere fra cattura audio, video o una combinazione delle due (tramite la proprietà StreamingCaptureMode);
  • selezionare la sorgente stream da usare per la cattura foto (tramite la proprietà PhotoCaptureSource).

Il prossimo listato mostra una versione modificata del metodo startDevice_click che sfrutta l'overload del metodo InitializeAsync.

function startDevice_click(args) {
	mediaCapture = new Windows.Media.Capture.MediaCapture();
	mediaCapture.onrecordlimitationexceeded = recordLimitationExceeded;
	mediaCapture.onfailed = mediaFailed;
	var cameraSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
	cameraSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audioAndVideo;
	cameraSettings.photoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.videoPreview;
	cameraSettings.realTimeModeEnabled = true;
	mediaCapture.initializeAsync(cameraSettings)
		.done(null, function (err) {
			errorMessage.innerHTML = "Inizializzazione fallita. Controlla i permessi per la webcam";
		});
}

MediaCaptureInitalizationSettings espone anche due proprietà, VideoDeviceId e AudioDeviceId, che permettono di specificare quale webcam e quale microfono utilizzare per la cattura. Il prossimo snippet mostra un esempio del loro utilizzo (l'enumerazione delle periferiche connesse al device sarà oggetto di uno specifico articolo di questa guida):

function startDevice_click(args) {
	mediaCapture = new Windows.Media.Capture.MediaCapture();
	mediaCapture.onrecordlimitationexceeded = recordLimitationExceeded;
	mediaCapture.onfailed = mediaFailed;
	var deviceInfo = Windows.Devices.Enumeration.DeviceInformation.findAllAsync(Windows.Devices.Enumeration.DeviceClass.videoCapture)
		.done(function (devices) {
			if (devices.length > 0) {
				var cameraSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
				cameraSettings.videoDeviceId = devices[0].id;
				cameraSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audioAndVideo;
				cameraSettings.photoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.videoPreview;
				cameraSettings.realTimeModeEnabled = true;
				mediaCapture.initializeAsync(cameraSettings)
					.done(null, function (err) {
						errorMessage.innerHTML = "Inizializzazione fallita. Controlla i permessi per la webcam";
					});
			} else {
				errorMessage.innerHTML = "Nessuna webcam connessa";
			}
		}, function (err) {
			// gestire l'errore
		});
}

L'ultimo passaggio consiste nel registrare lo stream proveniente dalla webcam per salvarlo nella libreria Videos dell'utente (di qui la necessità di dichiarare la relative "capability" nell'application manifest):

app.onloaded = function () {
	btnStartDevice.addEventListener("click", startDevice_click);
	btnStartPreview.addEventListener("click", startPreview_click);
	btnTakePhoto.addEventListener("click", takePicture_click);
	btnStartRecording.addEventListener("click", startRecording_click);
}
// ...
function startRecording_click(args) {
	var profile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp4(Windows.Media.MediaProperties.VideoEncodingQuality.qvga);
	try {
		Windows.Storage.KnownFolders.videosLibrary.createFileAsync("sample.mp4", Windows.Storage.CreationCollisionOption.generateUniqueName)
			.then(function (file) {
				mediaCapture.startRecordToStorageFileAsync(profile, file);
			})
			.done(null, function (err) {
				errorMessage.innerHTML = "Qualcosa è andato storto durante la registrazione.";
			});
	} catch (e) {
		// gestire l'errore
	}
}

Il codice sfrutta il metodo CreateFileAsync per salvare il video come storage file nella libreria Videos dell'utente. Nella promise then, il codice invoca il metodo StartRecordToStorageFileAsync della classe MediaCaptureper iniziare la registrazione usando il file specificato.

StartRecordToStorageFileAsync accetta un oggetto di tipo MediaEncodingProfile come primo parametro, che descrive il profilo di codifica per il file audio o video, inclusa la descrizione del formato (altri formati possibili, oltre al formato MP4, sono: Windows Media Video, M4a, MP3 e Windows Media Audio, o WMA) e della qualità di codifica.

La classe MediaCapture espone anche un metodo StartRecordToStreamAsync per registrare un random-access stream; e un metodo StartRecordToCustomSinkAsync method, con due diverse firme, per inviare lo stream a un media sink personalizzato (un media sink è un oggetto in grado di ricevere stream di dati audio e video; per ulteriori informazioni si rinvia alla documentazione su MSDN).

Durante le operazioni di registrazione, è possibile aggiustare alcune impostazioni di base della periferica di cattura tramite la classe CameraOptionsUI, la quale espone un singolo metodo, Show, per mostrare all'utente un pannello flyout con alcune opzioni di base per la cattura di foto, audio e video. Questo metodo accetta come parametro l'oggetto MediaCapture corrente. Il seguente codice ne mostra un esempio:

app.onloaded = function () {
	btnStartDevice.addEventListener("click", startDevice_click);
	btnStartPreview.addEventListener("click", startPreview_click);
	btnTakePhoto.addEventListener("click", takePicture_click);
	btnStartRecording.addEventListener("click", startRecording_click);
	btnShowSettings.addEventListener("click", showSettings_click);
}
// ...
function showSettings_click(args) {
	if (mediaCapture != null) {
		Windows.Media.Capture.CameraOptionsUI.show(mediaCapture);
	}
}

Il pannello di configurazione della webcam è mostrato nella prossima immagine:

Infine, per interrompere la registrazione del video, è sufficiente invocare il metodo StopRecordAsync, come mostrato qui di seguito:

app.onloaded = function () {
	btnStartDevice.addEventListener("click", startDevice_click);
	btnStartPreview.addEventListener("click", startPreview_click);
	btnTakePhoto.addEventListener("click", takePicture_click);
	btnStartRecording.addEventListener("click", startRecording_click);
	btnShowSettings.addEventListener("click", showSettings_click);
	btnStopRecording.addEventListener("click", stopRecording_click);
}
// ...
function stopRecording_click(args) {
	if (mediaCapture != null) {
		mediaCapture.stopRecordAsync().done(null, function (err) {
			// gestire l'errore
		});
	}
}

Per provare le API della classe MediaCapture possiamo usare il seguente codice HTML come riferimento per la tua pagina default.html:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>Demo.Html.t.MediaCapture.JS</title>
	<!-- WinJS references -->
	<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
	<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
	<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
	<!-- Demo.Html.t.MediaCapture.JS references -->
	<link href="/css/default.css" rel="stylesheet" />
	<script src="/js/default.js"></script>
</head>
<body>
<div id="container">
	<div id="previewBox">
		<div class="caption" id="previewCaption">Preview</div>
		<video id="previewVideo" width="400" height="300" />
	</div>
	<div id="photoCapture">
		<div class="caption" id="photoCaption">Captured Images</div>
		<img id="photoImage" src="images/placeholder.png" width="400" height="300" />
	</div>
	<div id="errorMessage"></div>
</div>
<div id="buttonRow">
	<span>
		<button class="button" id="btnStartDevice">Start Device</button>
		<button class="button" id="btnStartPreview">Start Preview</button>
		<button class="button" id="btnTakePhoto">Take Photo</button>
		<button class="button" id="btnStartRecording">Start Recording</button>
		<button class="button" id="btnStopRecording">Stop Recording</button>
		<button class="button" id="btnShowSettings">Show Settings</button>
	</span>
</div>
</body>
</html>

Catturare l'audio del microfono

Finora abbiamo visto come catturare immagini e video, mentre l'audio è stato registrato come parte dello stream proveniente dalla webcam. La cattura di audio proveniente da un'altra periferica, tipicamente un microfono, segue comunque lo stesso identico pattern visto finora. Il prossimo listato ne mostra un esempio:

function startDevice_click(args) {
	mediaCapture = new Windows.Media.Capture.MediaCapture();
	mediaCapture.onrecordlimitationexceeded = recordLimitationExceeded;
	mediaCapture.onfailed = mediaFailed;
	var deviceInfo = Windows.Devices.Enumeration.DeviceInformation
		.findAllAsync(Windows.Devices.Enumeration.DeviceClass.audioCapture)
			.done(function (devices) {
				if (devices.length > 0) {
					var audioSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
					audioSettings.audioDeviceId = devices[0].id;
					audioSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
					mediaCapture.initializeAsync(audioSettings)
						.done(null, function (err) {
							errorMessage.innerHTML = "Qualcosa è andato storto nell'inizializzare il mic. Controlla i permessi."
						});
				} else {
					errorMessage.innerHTML = "Nessun microfono connesso";
				}
			}, function (err) {
				// gestire l'eccezione
			});
}
function startRecording_click(args) {
	var profile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.high);
	try {
		Windows.Storage.KnownFolders.videosLibrary.createFileAsync("sample.mp3", Windows.Storage.CreationCollisionOption.generateUniqueName)
			.then(function (file) {
				mediaCapture.startRecordToStorageFileAsync(profile, file)
			})
			.done(null, function (err) {
				errorMessage.innerHTML = "Something went wrong while recording audio.";
			});
	} catch (e) {
		// gestire l'eccezione
	}
}

In questo articolo abbiamo visto come utilizzare entrambe le tipologie di API esposte da WinRT per interagire con periferiche di cattura audio e video: quella più semplice, rappresentata dalla classe CameraCaptureUI, che permette allo sviluppatore di sfruttare la user interface standard, senza doversi preoccupare dei dettagli implementativi; e quella più "avanzata", costituita dalla classe MediaCapture, che invece assicura un controllo maggiore sull'intero flusso di cattura audio/video, inclusa l'eventuale personalizzazione della user interface.

Ti consigliamo anche