WP8出来好一段时间了,新出的AudioVideoCaptureDevice类自定义功能比WP7的CaptureSource强大的多,但网上比较全面的中文实例还比较少,分享一个最近做的小实例给大家参考。
一、实现的功能
1、实现视频和音频的采集并保存
2、允许切换前后摄像头
3、录像过程中可以随时截图
4、录像后视频播放
二、需要的权限
1、需要访问前后摄像头的权限(ID_CAP_ISV_CAMERA)
2、需要访问麦克风的权限(ID_CAP_MICROPHONE)
三 、UI部分
1、使用一个Rectangle控件实时显示摄像头采集到的画面
2、使用一个Image控件来显示视频截图
3、使用一个MediaElement控件来播放录制好的视频
4、使用一个HyperLinkButton控件来切换摄像头
<Canvas x:Name="LayoutRoot" Background="Transparent"> <!--Camera viewfinder >--> <Rectangle x:Name="Re_video" Width="640" Height="480"> <Rectangle.Fill> <VideoBrush x:Name="TheVideoBrush"></VideoBrush> </Rectangle.Fill> </Rectangle> <MediaElement x:Name="VideoPlayer" Width="480" Height="640" AutoPlay="True" RenderTransformOrigin="0.5, 0.5" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="Fill" Canvas.Left="0"/> <Image Name="imgCapture" Width="320" Height="240" Margin="20 0 0 0" /> <Grid Margin="20,10" Width="450"> <HyperlinkButton Width="50" x:Name="hyper_changes" Click="hyper_changes_Click" HorizontalAlignment="Right"> <HyperlinkButton.Template> <ControlTemplate> <Image Source="/Images/Camera/changes.png" /> </ControlTemplate> </HyperlinkButton.Template> </HyperlinkButton> </Grid> </Canvas>
四、代码部分
1、定义基础变量
//目录 private string m_path = "Vedio"; //视频文件名 private string m_filename = string.Empty; //用于设置摄像头旋转的角度 RotateTransform rt1 = new RotateTransform(); //用于设置使用前置还是后置的摄像头 CameraSensorLocation sensorLocation = CameraSensorLocation.Front; //随机访问数据流 private Windows.Storage.Streams.IRandomAccessStream m_iRandomAccessStream; //捕获视频设备对象 private Windows.Phone.Media.Capture.AudioVideoCaptureDevice m_captureDevice;
2、初始化录像设备
/// <summary> /// 初始化捕获设备, /// </summary> private async void Init() { try { if (m_captureDevice != null) { m_captureDevice.Dispose(); m_captureDevice = null; } //获取视频捕获设备 m_captureDevice = await AudioVideoCaptureDevice.OpenAsync(sensorLocation, new Windows.Foundation.Size(640, 480)); int sensorOrientation = (Int32)this.m_captureDevice.SensorRotationInDegrees; if (sensorLocation == CameraSensorLocation.Back) { rt1.CenterX = 230; rt1.CenterY = 240; rt1.Angle = 90; Re_video.RenderTransform = rt1; } else { rt1.CenterX = 320; rt1.CenterY = 330; rt1.Angle = 270; Re_video.RenderTransform = rt1; } m_captureDevice.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, sensorLocation == CameraSensorLocation.Back ? 90 : 270); //m_captureDevice.SetProperty(KnownCameraAudioVideoProperties.VideoFrameRate, 20); m_captureDevice.SetProperty(KnownCameraAudioVideoProperties.UnmuteAudioWhileRecording, true); m_captureDevice.VideoEncodingFormat = CameraCaptureVideoFormat.H264; TheVideoBrush.SetSource(m_captureDevice); //设置视频数据格式 } catch (Exception e) { throw e; } }
注意:
1)、KnownCameraGeneralProperties.EncodeWithOrientation 可以控制前后摄像头旋转的角度, 默认情况下WP获取的视频都是倒着显示的
2)、KnownCameraAudioVideoProperties.UnmuteAudioWhileRecording 是让视频在录制时取消静音,默认情况下是静音的
3)、CameraCaptureVideoFormat.H264; 使用H264编码方式
3、开始录制视频
//开始录制 private async void StartRecord() { m_filename = Guid.NewGuid().ToString() + ".mp4"; try { StorageFile file = null; StorageFolder folder = ApplicationData.Current.LocalFolder; using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()) { //不存在目录,则创建 if (!isolatedStorageFile.DirectoryExists(m_path)) { isolatedStorageFile.CreateDirectory(m_path); } } folder = await folder.GetFolderAsync(m_path); m_iRandomAccessStream = null; //创建视频文件 file = await folder.CreateFileAsync(m_filename, CreationCollisionOption.ReplaceExisting); m_iRandomAccessStream = await file.OpenAsync(FileAccessMode.ReadWrite); //开始捕获视频数据并写到随机流中 await m_captureDevice.StartRecordingToStreamAsync(m_iRandomAccessStream); } catch (Exception ex) { throw ex; } }
4、录制过程中实现截图功能
/// <summary> /// 截取视频图像 /// </summary> private void GetPreview() { WriteableBitmap wBitmap = new WriteableBitmap(640, 480); wBitmap.Render(Re_video, new MatrixTransform());//截取视频 wBitmap.Invalidate(); imgCapture.Source = wBitmap; }
注意:这段代码的思路其实是截取Rectangle控件的UI界面
5、停止录制视频
//停止录制 private async void StopRecord() { try { await m_captureDevice.StopRecordingAsync(); m_iRandomAccessStream.Dispose(); } catch (Exception ex) { throw ex; } }
6、播放录制好的视频
/// <summary> /// 播放录制的视频 /// </summary> private void PlayVideo() { string path = m_path + "/" + m_filename; using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read)) { VideoPlayer.SetSource(fileStream); fileStream.Dispose(); fileStream.Close(); } } }
7、切换前后摄像头
/// <summary> /// 切换前后摄像头 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void hyper_changes_Click(object sender, System.Windows.RoutedEventArgs e) { if (sensorLocation == CameraSensorLocation.Front) sensorLocation = CameraSensorLocation.Back; else sensorLocation = CameraSensorLocation.Front; Init(); }
至此,大致功能全部实现了, 当然还需要处理一些按钮事件, 这些直接看附件吧:
http://share.weiyun.com/d89188c5490e6bf95c7f7aa08c0f81bc
欢迎有共同兴趣的朋友交流, 微博地址:http://weibo.com/yanghongjin
如果觉得本文对你有帮助,可以微信扫描以下二维码请我喝杯咖啡