zoukankan      html  css  js  c++  java
  • 使用WP8最新的AudioVideoCaptureDevice类制作录像应用

    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

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

  • 相关阅读:
    Serilog 动态添加自定义属性
    C# 序列化与反序列化
    幂等设计
    服务无状态
    vue 显示 mysql 数据库表 Demo
    C# 调用 linux 函数 —— Linux 头文件目录位置
    创建可以在 Zynq 上运行的动态库
    C# 获取所在函数名
    Linux 关闭终端不结束进程
    C# 自动生成版本号
  • 原文地址:https://www.cnblogs.com/xxingmen/p/3329916.html
Copyright © 2011-2022 走看看