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

 

如果觉得本文对你有帮助,可以微信扫描以下二维码请我喝杯咖啡