與眾不同 windows phone (41) - 8.0 相機和照片: 通過 AudioVideoCaptureDevice 捕獲視頻和音頻
作者:webabcd
介紹
與眾不同 windows phone 8.0 之 相機和照片
- 通過 AudioVideoCaptureDevice 捕獲視頻和音頻
示例
演示 AudioVideoCaptureDevice(wp8)的應用
CameraAndPhoto/AudioVideoCaptureDeviceDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.CameraAndPhoto.AudioVideoCaptureDeviceDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel> <StackPanel Orientation="Horizontal"> <Canvas Width="240" Height="180" RenderTransformOrigin="0.5 0.5"> <Canvas.Background> <VideoBrush x:Name="videoBrush" /> </Canvas.Background> <Canvas.RenderTransform> <RotateTransform x:Name="rt" /> </Canvas.RenderTransform> </Canvas> <MediaElement Name="mediaElement" Width="240" Height="180" /> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0 50 0 0"> <Button Name="btnCapture" Content="錄像" Click="btnCapture_Click" /> <Button Name="btnStop" Content="停止" Click="btnStop_Click" IsEnabled="False" /> <Button Name="btnPlay" Content="播放" Click="btnPlay_Click" /> </StackPanel> <TextBlock x:Name="lblMsg" TextWrapping="Wrap" Margin="0 10 0 0" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
CameraAndPhoto/AudioVideoCaptureDeviceDemo.xaml.cs
/* * 演示 AudioVideoCaptureDevice(wp8)的應用 * * 關於 CaptureSource, FileSink(wp7)的應用參見 * http://www.cnblogs.com/webabcd/archive/2012/08/13/2635698.html * http://www.cnblogs.com/webabcd/archive/2012/08/15/2639428.html * * * 注: * 需要在 manifest 中增加配置 <Capability Name="ID_CAP_ISV_CAMERA" /> <Capability Name="ID_CAP_MICROPHONE" /> <Capability Name="ID_CAP_MEDIALIB_PHOTO" /> */ using System; using System.Collections.Generic; using System.Linq; using System.Windows; using Microsoft.Phone.Controls; using Windows.Phone.Media.Capture; using Microsoft.Devices; using Windows.Storage.Streams; using Windows.Storage; using Microsoft.Phone.Tasks; namespace Demo.CameraAndPhoto { public partial class AudioVideoCaptureDeviceDemo : PhoneApplicationPage { private AudioVideoCaptureDevice _captureDevice; private IRandomAccessStream _stream; public AudioVideoCaptureDeviceDemo() { InitializeComponent(); this.Loaded += AudioVideoCaptureDeviceDemo_Loaded; } private async void AudioVideoCaptureDeviceDemo_Loaded(object sender, RoutedEventArgs e) { // 一些概述類的說明 Summary(); // 是否有后置攝像頭 if (AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back)) { // 獲取后置攝像頭攝像時的可用分辨率 IReadOnlyList<Windows.Foundation.Size> supportedResolutions = AudioVideoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back); Windows.Foundation.Size resolution = supportedResolutions[0]; try { // 讓后置攝像頭以指定的分辨率捕獲鏡頭內容 _captureDevice = await AudioVideoCaptureDevice.OpenAsync(CameraSensorLocation.Back, resolution); // AudioVideoCaptureDevice.OpenForVideoOnlyAsync() - 僅捕獲視頻 // AudioVideoCaptureDevice.OpenForAudioOnlyAsync() - 僅捕獲音頻 // 錄像失敗時觸發的事件 _captureDevice.RecordingFailed += _captureDevice_RecordingFailed; /* * SetCaptureResolutionAsync() - 設置攝像的分辨率 * CaptureResolution - 獲取當前攝像的分辨率 * VideoEncodingFormat - 當前的視頻編碼格式 * AudioEncodingFormat - 當前的音頻編碼格式 * FocusRegion - 對焦區域 * SensorLocation - 當前攝像頭的位置(CameraSensorLocation 枚舉:Back 或 Front) * SensorRotationInDegrees - 獲取攝像頭傳感器相對於屏幕的旋轉度數 * FocusAsync() - 自動對焦 * ResetFocusAsync() - 復位對焦 */ /* * KnownCameraAudioVideoProperties 屬性集包括 * VideoFrameRate - 每秒抓取的視頻幀數 * H264EncodingProfile - H264 編碼的 profile(H264EncoderProfile 枚舉) * H264EncodingLevel - H264 編碼的 level(H264EncoderLevel 枚舉) * H264EnableKeyframes - 是否啟用關鍵幀 * H264QuantizationParameter - QP 值,低的 QP 會保留大部分空間的詳細信息,從而達到最佳質量,高的 QP 會在一定程度上造成質量的損失,但能幫助編碼器實現較低的比特率 * H264RequestDropNextNFrames - 指定編碼器應丟棄的幀數 * H264RequestIdrFrame - 此屬性設置為 true 時,系統請求編碼流程進行瞬時解碼刷新(IDR) * UnmuteAudioWhileRecording - 此屬性設置為 true 時,能在記錄期間為音頻取消靜音 * VideoTorchMode - 錄像時如何使用閃光燈(VideoTorchMode 枚舉:Off, Auto, On) * VideoTorchPower - 錄像時閃光燈的亮度,無單位且不同設備上的值不同 */ _captureDevice.SetProperty(KnownCameraAudioVideoProperties.H264EncodingProfile, H264EncoderProfile.Baseline); /* * KnownCameraGeneralProperties 屬性集包括 * AutoFocusRange - 自動對焦的范圍(AutoFocusRange 枚舉,包括微距等) * EncodeWithOrientation - 視頻編碼時的旋轉角度,必須是 90 的倍數 * SpecifiedCaptureOrientation - 元數據中的旋轉角度,必須是 90 的倍數 * IsShutterSoundEnabledByUser - 用戶是否啟用了快門聲音,只讀 * IsShutterSoundRequiredForRegion - 運行應用程序的區域是否需要快門聲音(有些區域為了保護隱私,要求照相或錄像必須要有快門聲音),只讀 * PlayShutterSoundOnCapture - 指定捕獲時是否播放快門聲音 * ManualFocusPosition - 手動對焦的位置 */ _captureDevice.SetProperty(KnownCameraGeneralProperties.AutoFocusRange, AutoFocusRange.Normal); _captureDevice.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, _captureDevice.SensorRotationInDegrees); // 獲取指定屬性的值 // _captureDevice.GetProperty(KnownCameraGeneralProperties.IsShutterSoundEnabledByUser); /* * 獲取指定的范圍類屬性在當前攝像頭中所允許的值的范圍 */ // AudioVideoCaptureDevice.GetSupportedPropertyRange(CameraSensorLocation.Back, KnownCameraAudioVideoProperties.H264QuantizationParameter); /* * 獲取指定的值類屬性在當前攝像頭中所允許的值的列表 */ // AudioVideoCaptureDevice.GetSupportedPropertyValues(CameraSensorLocation.Back, KnownCameraAudioVideoProperties.H264EncodingProfile); // 實時顯示捕獲的內容 videoBrush.SetSource(_captureDevice); // 擴展方法來自:Microsoft.Devices.CameraVideoBrushExtensions rt.Angle = _captureDevice.SensorRotationInDegrees; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } else { MessageBox.Show("沒有后置攝像頭"); } } // 錄像失敗 void _captureDevice_RecordingFailed(AudioVideoCaptureDevice sender, CaptureFailedEventArgs args) { this.Dispatcher.BeginInvoke(delegate() { MessageBox.Show("error: " + args.ErrorCode.ToString()); }); } // 開始錄像 private async void btnCapture_Click(object sender, RoutedEventArgs e) { try { // 獲取應用程序數據存儲文件夾 StorageFolder applicationFolder = ApplicationData.Current.LocalFolder; // 在指定的應用程序數據存儲文件夾內創建指定的文件 StorageFile storageFile = await applicationFolder.CreateFileAsync("webabcdTest.mp4", CreationCollisionOption.ReplaceExisting); // 打開文件流,准備寫入錄像數據 _stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite); // 錄制視頻到指定的流 await _captureDevice.StartRecordingToStreamAsync(_stream); btnCapture.IsEnabled = false; btnStop.IsEnabled = true; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } // 停止錄像 private async void btnStop_Click(object sender, RoutedEventArgs e) { // 停止錄像 await _captureDevice.StopRecordingAsync(); _stream.Dispose(); btnCapture.IsEnabled = true; btnStop.IsEnabled = false; } // 播放錄制的內容 private void btnPlay_Click(object sender, RoutedEventArgs e) { // 啟動媒體播放器,播放錄制的內容 MediaPlayerLauncher mediaPlayerLauncher = new MediaPlayerLauncher(); // new Uri("webabcdTest.mp4", UriKind.Relative) 結合 MediaLocationType.Data,則系統會先在應用程序存儲的 Local 目錄下找,找不到再到 Local/IsolatedStorage 目錄下找 mediaPlayerLauncher.Media = new Uri("webabcdTest.mp4", UriKind.Relative); mediaPlayerLauncher.Location = MediaLocationType.Data; mediaPlayerLauncher.Controls = MediaPlaybackControls.Pause | MediaPlaybackControls.Stop; mediaPlayerLauncher.Orientation = MediaPlayerOrientation.Landscape; mediaPlayerLauncher.Show(); } private void Summary() { lblMsg.Text = ""; // 獲取電話上的可用攝像頭 foreach (CameraSensorLocation csl in AudioVideoCaptureDevice.AvailableSensorLocations) { // Back 或 Front lblMsg.Text += "攝像頭:" + csl.ToString(); lblMsg.Text += System.Environment.NewLine; // 攝像所支持的分辨率 lblMsg.Text += "攝像的可用分辨率:"; foreach (var size in AudioVideoCaptureDevice.GetAvailableCaptureResolutions(csl)) { lblMsg.Text += size.Width + "*" + size.Height + " "; } lblMsg.Text += System.Environment.NewLine; lblMsg.Text += System.Environment.NewLine; // 關於 CameraButtons 參見以前的文章:http://www.cnblogs.com/webabcd/archive/2012/08/15/2639428.html // CameraButtons.ShutterKeyHalfPressed 事件,CameraButtons.ShutterKeyPressed 事件,CameraButtons.ShutterKeyReleased 事件 } lblMsg.Text += "終端所支持的視頻編碼格式:"; foreach (CameraCaptureVideoFormat format in AudioVideoCaptureDevice.SupportedVideoEncodingFormats) { lblMsg.Text += format.ToString() + " "; } lblMsg.Text += System.Environment.NewLine; lblMsg.Text += "終端所支持的音頻編碼格式:"; foreach (CameraCaptureAudioFormat format in AudioVideoCaptureDevice.SupportedAudioEncodingFormats) { lblMsg.Text += format.ToString() + " "; } lblMsg.Text += System.Environment.NewLine; } } }
OK
[源碼下載]
