Silverlight之视频录制

Silverlight之视频录制,第1张

概述     Silverlight之视频录制                      分类:             Silverlight              2011-11-30 21:55     459人阅读     评论(1)     收藏     举报     目录(?)[+] 一NESL项目简介 二使用NESL实现视频录制 三注意 摘要:在前两篇Silverlight的文章中跟      Silverlight之视频录制                      分类:             Silverlight              2011-11-30 21:55     459人阅读     评论(1)     收藏     举报    

目录(?)[+]

一NESL项目简介 二使用NESL实现视频录制 三注意

摘要:在前两篇Silverlight的文章中跟大家一块学习了Silverlight的基础知识、Silverlight摄像头麦克风的相关 *** 作以及截图、声音录制等,在文章后面也简单的说明了为什么没有视频录制,今天就和大家一块看一下上一节中最后的一个问题:如何使用Silverlight进行视频录制。

主要内容:

1.nesL项目简介

2.使用nesL实现视频录制

3.注意

一、nesL项目简介

在silverlight 中如何录制视频?相信这个问题有不少朋友都搜索过,但是好像目前还没有见到很好的答案,究其原因其实就是视频编码问题。当然也有朋友提到直接进行截图,只要每秒截取足够多的图片,然后依次播放就可以形成视频。但是我看到国外一个朋友使用此方法进行了几十秒的视频录制,其文件大小就达到了百兆级别,而且还进行了优化。因此这种方式要实现视频录制就目前而言还不是很合适。那么到底有没有好的方法呢?答案是有,但有限制,那就是借助于nesL。

Native Extensions for Silverlight(简称nesL)是由微软Silverlight团队进行开发,其目的主要为了增强Silverlight Out-of-browser离线应用的功能。大家都知道虽然Silverlight 4的OOB应用支持信任人权限提升功能,允许Silverlight的OOB应用对COM组件的访问,但对绝大多数windows API仍旧无法调用,而nesL的出现正是为了解决这个问题。在最新的nesL 2.0中包含了大量有用的功能,而这其中就包括今天要说的视频编码部分。在nesL中有一个类库Microsoft.Silverlight.windows.LocalEncode.dll主要负责本地视频和音频编码,这里就是用此类库来解决上面提到的视频录制问题。

二、使用nesL实现视频录制

在Microsoft.Silverlight.windows.LocalEncode.dll中一个核心类就是EncodeSession,它负责音频和视频的编码输出工作。使用EncodeSession进行视频录制大概分为下面两步:

1.准备输入输出信息

在这个过程中需要定义VIDeinputFormatInfo、AudioinputFormatInfo、VIDeoOutputFormatInfo、AudioOutputFormatInfo和OutputContainerInfo,然后调用EncodeSession.Prepare()方法。

2.捕获视频输出

当输入输出信息准备好之后接下来就是调用EncodeSession.Start()方法进行视频编码输出。当然为了接收音频和视频数据必须准备两个sink类,分别继承于AudioSink和VIDeosink,在这两个sink中指定CaptureSource,并且在对应的OnSample中调用EncodeSession的WirteVIDeoSample()和WirteAudioSample()接收并编码数据(关于AudioSink在前面的文章中已经说过,VIDeosink与之类似)。

知道了EncodeSession的使用方法后下面就将其 *** 作进行简单封装,LocalCamera.cs是本例中的核心类:

[csharp] view plain copy print ? using System;   using System.Collections.ObjectModel;   using System.IO;   using System.windows;   using System.windows.Threading;   using System.windows.Media;   using System.windows.Controls;   using System.windows.Shapes;   using Microsoft.Silverlight.windows.LocalEncode;      namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa   {       /// <summary>       /// 编码状态       /// </summary>       public enum EncodeSessionState       {           Start,           Pause,           Stop       }       /// <summary>       /// 本地视频对象       /// </summary>       public class LocalCamera       {           private string _saveFullPath = "";           private uint _vIDeoWIDth = 640;           private uint _vIDeoHeight = 480;           private VIDeosinkExtensions _vIDeosink = null;           private AudioSinkExtensions _audioSink= null;           private EncodeSession _encodeSession = null;           private UserControl _page = null;           private CaptureSource _cSource = null;           public LocalCamera(UserControl page,VIDeoFormat vIDeoFormat,AudioFormat audioFormat)           {               //this._saveFullPath = saveFullPath;               this._vIDeoWIDth = (uint)vIDeoFormat.PixelWIDth;               this._vIDeoHeight = (uint)vIDeoFormat.PixelHeight;               this._page = page;               this.SessionState = EncodeSessionState.Stop;               //this._encodeSession = new EncodeSession();               _cSource = new CaptureSource();               this.VIDeoDevice = DefaultVIDeoDevice;               this.VIDeoDevice.DesiredFormat = vIDeoFormat;               this.AudioDevice = DefaultAudioDevice;               this.AudioDevice.DesiredFormat = audioFormat;               _cSource.VIDeoCaptureDevice = this.VIDeoDevice;               _cSource.AudioCaptureDevice = this.AudioDevice;               audioinputFormatInfo = new AudioinputFormatInfo() { SourceCompressionType = FormatConstants.AudioFormat_PCM };               vIDeoinputFormatInfo = new VIDeoinputFormatInfo() { SourceCompressionType = FormatConstants.VIDeoFormat_ARGB32 };               audioOutputFormatInfo = new AudioOutputFormatInfo() { TargetCompressionType = FormatConstants.AudioFormat_AAC };               vIDeoOutputFormatInfo = new VIDeoOutputFormatInfo() { TargetCompressionType = FormatConstants.VIDeoFormat_H264 };               outputContainerInfo = new OutputContainerInfo() { ContainerType = FormatConstants.TranscodeContainerType_MPEG4 };           }              public LocalCamera(UserControl page,VIDeoCaptureDevice vIDeoCaptureDevice,AudioCaptureDevice audioCaptureDevice, VIDeoFormat vIDeoFormat, AudioFormat audioFormat)           {               //this._saveFullPath = saveFullPath;               this._vIDeoWIDth = (uint)vIDeoFormat.PixelWIDth;               this._vIDeoHeight = (uint)vIDeoFormat.PixelHeight;               this._page = page;               this.SessionState = EncodeSessionState.Stop;               //this._encodeSession = new EncodeSession();               _cSource = new CaptureSource();               this.VIDeoDevice = vIDeoCaptureDevice;               this.VIDeoDevice.DesiredFormat = vIDeoFormat;               this.AudioDevice = audioCaptureDevice;               this.AudioDevice.DesiredFormat = audioFormat;               _cSource.VIDeoCaptureDevice = this.VIDeoDevice;               _cSource.AudioCaptureDevice = this.AudioDevice;               audioinputFormatInfo = new AudioinputFormatInfo() { SourceCompressionType = FormatConstants.AudioFormat_PCM };               vIDeoinputFormatInfo = new VIDeoinputFormatInfo() { SourceCompressionType = FormatConstants.VIDeoFormat_ARGB32 };               audioOutputFormatInfo = new AudioOutputFormatInfo() { TargetCompressionType = FormatConstants.AudioFormat_AAC };               vIDeoOutputFormatInfo = new VIDeoOutputFormatInfo() { TargetCompressionType = FormatConstants.VIDeoFormat_H264 };               outputContainerInfo = new OutputContainerInfo() { ContainerType = FormatConstants.TranscodeContainerType_MPEG4 };           }              public EncodeSessionState SessionState            {               get;               set;           }           public EncodeSession Session           {               get               {                   return _encodeSession;               }               set               {                   _encodeSession = value;               }           }           /// <summary>           /// 编码对象所在用户控件对象           /// </summary>           public UserControl OwnPage           {               get               {                   return _page;               }               set               {                   _page = value;               }           }           /// <summary>           /// 捕获源           /// </summary>           public CaptureSource Source           {               get               {                   return _cSource;               }           }           /// <summary>           ///  *** 作音频对象           /// </summary>           public AudioSinkExtensions AudioSink           {               get               {                   return _audioSink;               }           }              public static VIDeoCaptureDevice DefaultVIDeoDevice           {               get               {                   return CaptureDeviceConfiguration.GetDefaultVIDeoCaptureDevice();               }           }                      public static ReadonlyCollection<VIDeoCaptureDevice> AvailableVIDeoDevice           {               get               {                   return CaptureDeviceConfiguration.GetAvailableVIDeoCaptureDevices();               }           }              public VIDeoCaptureDevice VIDeoDevice           {               get;               set;           }              public static AudioCaptureDevice DefaultAudioDevice           {               get               {                   return CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();               }           }           public static ReadonlyCollection<AudioCaptureDevice> AvailableAudioDevice           {               get               {                   return CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();               }           }              public AudioCaptureDevice AudioDevice           {               get;               set;           }              private Object lockObj = new object();           internal VIDeoinputFormatInfo vIDeoinputFormatInfo;           internal AudioinputFormatInfo audioinputFormatInfo;           internal VIDeoOutputFormatInfo vIDeoOutputFormatInfo;           internal AudioOutputFormatInfo audioOutputFormatInfo;           internal OutputContainerInfo outputContainerInfo;           /// <summary>           /// 视频录制           /// </summary>           public voID StartRecord()           {               lock (lockObj)               {                   if (this.SessionState == EncodeSessionState.Stop)                   {                       _vIDeosink = new VIDeosinkExtensions(this);                       _audioSink = new AudioSinkExtensions(this);                       //_audioSink.VolumnChange += new AudioSinkExtensions.VolumnChangeHanlder(_audioSink_VolumnChange);                       if (_encodeSession == null)                       {                           _encodeSession = new EncodeSession();                       }                       PrepareFormatInfo(_cSource.VIDeoCaptureDevice.DesiredFormat, _cSource.AudioCaptureDevice.DesiredFormat);                       _encodeSession.Prepare(vIDeoinputFormatInfo, audioinputFormatInfo, vIDeoOutputFormatInfo, audioOutputFormatInfo, outputContainerInfo);                       _encodeSession.Start(false, 200);                       this.SessionState = EncodeSessionState.Start;                   }               }           }           /// <summary>           /// 音量大小指示           /// </summary>           /// <param name="sender"></param>           /// <param name="e"></param>           //voID _audioSink_VolumnChange(object sender, VolumnChangeArgs e)           //{           //    this.OwnPage.dispatcher.BeginInvoke(new Action(() =>           //    {           //        (           //            this.OwnPage.Tag as Progressbar).Value = e.Volumn;           //    }));           //}              /// <summary>           /// 暂停录制           /// </summary>           public voID PauseRecord()           {               lock (lockObj)               {                   this.SessionState = EncodeSessionState.Pause;                   _encodeSession.Pause();               }           }           /// <summary>           /// 停止录制           /// </summary>           public voID StopRecord()           {               lock (lockObj)               {                   this.SessionState = EncodeSessionState.Stop;                   _encodeSession.Shutdown();                   _vIDeosink = null;                   _audioSink = null;               }           }              /// <summary>           /// 准备编码信息           /// </summary>           /// <param name="vIDeoFormat"></param>           /// <param name="audioFormat"></param>           private voID PrepareFormatInfo(VIDeoFormat vIDeoFormat, AudioFormat audioFormat)           {               uint FrameRateratioNumerator = 0;               uint FrameRaterationDenominator = 0;               FormatConstants.FrameRatetoRatio((float)Math.Round(vIDeoFormat.FramesPerSecond, 2), ref FrameRateratioNumerator, ref FrameRaterationDenominator);                  vIDeoinputFormatInfo.FrameRateratioNumerator = FrameRateratioNumerator;               vIDeoinputFormatInfo.FrameRateratioDenominator = FrameRaterationDenominator;               vIDeoinputFormatInfo.FrameWIDthInPixels = _vIDeoWIDth;               vIDeoinputFormatInfo.FrameHeightInPixels = _vIDeoHeight ;               vIDeoinputFormatInfo.StrIDe = (int)_vIDeoWIDth*-4;                  vIDeoOutputFormatInfo.FrameRateratioNumerator = FrameRateratioNumerator;               vIDeoOutputFormatInfo.FrameRateratioDenominator = FrameRaterationDenominator;               vIDeoOutputFormatInfo.FrameWIDthInPixels = vIDeoOutputFormatInfo.FrameWIDthInPixels == 0 ? (uint)vIDeoFormat.PixelWIDth : vIDeoOutputFormatInfo.FrameWIDthInPixels;               vIDeoOutputFormatInfo.FrameHeightInPixels = vIDeoOutputFormatInfo.FrameHeightInPixels == 0 ? (uint)vIDeoFormat.PixelHeight : vIDeoOutputFormatInfo.FrameHeightInPixels;                  audioinputFormatInfo.BitsPerSample = (uint)audioFormat.BitsPerSample;               audioinputFormatInfo.SamplesPerSecond = (uint)audioFormat.SamplesPerSecond;               audioinputFormatInfo.ChannelCount = (uint)audioFormat.Channels;               if (outputContainerInfo.filePath == null || outputContainerInfo.filePath == string.Empty)               {                   _saveFullPath=System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyVIDeos), "cCameraRecordVIDeo.tmp");               }               outputContainerInfo.filePath = _saveFullPath;               //outputContainerInfo.filePath = _saveFullPath;               if (audioOutputFormatInfo.AverageBitrate == 0)                   audioOutputFormatInfo.AverageBitrate = 24000;               if (vIDeoOutputFormatInfo.AverageBitrate == 0)                   vIDeoOutputFormatInfo.AverageBitrate = 2000000;           }              /// <summary>           /// 开始捕获           /// </summary>           public voID StartCaptrue()           {               if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())               {                   _cSource.Start();               }           }              /// <summary>           /// 停止捕获           /// </summary>           public voID StopCapture()           {               _vIDeosink = null;               _audioSink = null;               _cSource.Stop();           }              /// <summary>           /// 获得视频           /// </summary>           /// <returns></returns>           public VIDeoBrush GetVIDeoBrush()           {               VIDeoBrush vBrush = new VIDeoBrush();               vBrush.SetSource(_cSource);               return vBrush;           }              /// <summary>           /// 获得视频           /// </summary>           /// <returns></returns>           public Rectangle GetVIDeoRectangle()           {               Rectangle rctg = new Rectangle();               rctg.WIDth = this._vIDeoWIDth;               rctg.Height = this._vIDeoHeight;               rctg.Fill = GetVIDeoBrush();               return rctg;           }              /// <summary>           /// 保存视频           /// </summary>           public voID SaveRecord()           {               if (_saveFullPath == string.Empty)               {                   MessageBox.Show("尚未录制视频,无法进行保存!""系统提示", MessageBoxbutton.OK);                   return;               }               SavefileDialog sfd = new SavefileDialog               {                   Filter = "MP4 files (*.mp4)|*.mp4",                   DefaultExt = ".mp4",                   FilterIndex = 1               };                  if ((bool)sfd.ShowDialog())               {                   using (Stream stm=sfd.Openfile())                   {                       fileStream fs = new fileStream(_saveFullPath, fileMode.Open, fileAccess.Read);                       try                       {                           byte[] buffur = new byte[fs.Length];                           fs.Read(buffur, 0, (int)fs.Length);                           stm.Write(buffur, (int)buffur.Length);                           fs.Close();                           file.Delete(_saveFullPath);                       }                       catch (IOException ioe)                       {                           MessageBox.Show("文件保存失败!错误信息如下:"+Environment.Newline+ioe.Message,"系统提示",MessageBoxbutton.OK);                       }                       stm.Close();                   }               }           }       }   }  
using System;using System.Collections.ObjectModel;using System.IO;using System.windows;using System.windows.Threading;using System.windows.Media;using System.windows.Controls;using System.windows.Shapes;using Microsoft.Silverlight.windows.LocalEncode;namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa{    /// <summary>    /// 编码状态    /// </summary>    public enum EncodeSessionState    {        Start,Pause,Stop    }    /// <summary>    /// 本地视频对象    /// </summary>    public class LocalCamera    {        private string _saveFullPath = "";        private uint _vIDeoWIDth = 640;        private uint _vIDeoHeight = 480;        private VIDeosinkExtensions _vIDeosink = null;        private AudioSinkExtensions _audioSink= null;        private EncodeSession _encodeSession = null;        private UserControl _page = null;        private CaptureSource _cSource = null;        public LocalCamera(UserControl page,VIDeoFormat vIDeoFormat,AudioFormat audioFormat)        {            //this._saveFullPath = saveFullPath;            this._vIDeoWIDth = (uint)vIDeoFormat.PixelWIDth;            this._vIDeoHeight = (uint)vIDeoFormat.PixelHeight;            this._page = page;            this.SessionState = EncodeSessionState.Stop;            //this._encodeSession = new EncodeSession();            _cSource = new CaptureSource();            this.VIDeoDevice = DefaultVIDeoDevice;            this.VIDeoDevice.DesiredFormat = vIDeoFormat;            this.AudioDevice = DefaultAudioDevice;            this.AudioDevice.DesiredFormat = audioFormat;            _cSource.VIDeoCaptureDevice = this.VIDeoDevice;            _cSource.AudioCaptureDevice = this.AudioDevice;            audioinputFormatInfo = new AudioinputFormatInfo() { SourceCompressionType = FormatConstants.AudioFormat_PCM };            vIDeoinputFormatInfo = new VIDeoinputFormatInfo() { SourceCompressionType = FormatConstants.VIDeoFormat_ARGB32 };            audioOutputFormatInfo = new AudioOutputFormatInfo() { TargetCompressionType = FormatConstants.AudioFormat_AAC };            vIDeoOutputFormatInfo = new VIDeoOutputFormatInfo() { TargetCompressionType = FormatConstants.VIDeoFormat_H264 };            outputContainerInfo = new OutputContainerInfo() { ContainerType = FormatConstants.TranscodeContainerType_MPEG4 };        }        public LocalCamera(UserControl page,VIDeoCaptureDevice vIDeoCaptureDevice,AudioCaptureDevice audioCaptureDevice,AudioFormat audioFormat)        {            //this._saveFullPath = saveFullPath;            this._vIDeoWIDth = (uint)vIDeoFormat.PixelWIDth;            this._vIDeoHeight = (uint)vIDeoFormat.PixelHeight;            this._page = page;            this.SessionState = EncodeSessionState.Stop;            //this._encodeSession = new EncodeSession();            _cSource = new CaptureSource();            this.VIDeoDevice = vIDeoCaptureDevice;            this.VIDeoDevice.DesiredFormat = vIDeoFormat;            this.AudioDevice = audioCaptureDevice;            this.AudioDevice.DesiredFormat = audioFormat;            _cSource.VIDeoCaptureDevice = this.VIDeoDevice;            _cSource.AudioCaptureDevice = this.AudioDevice;            audioinputFormatInfo = new AudioinputFormatInfo() { SourceCompressionType = FormatConstants.AudioFormat_PCM };            vIDeoinputFormatInfo = new VIDeoinputFormatInfo() { SourceCompressionType = FormatConstants.VIDeoFormat_ARGB32 };            audioOutputFormatInfo = new AudioOutputFormatInfo() { TargetCompressionType = FormatConstants.AudioFormat_AAC };            vIDeoOutputFormatInfo = new VIDeoOutputFormatInfo() { TargetCompressionType = FormatConstants.VIDeoFormat_H264 };            outputContainerInfo = new OutputContainerInfo() { ContainerType = FormatConstants.TranscodeContainerType_MPEG4 };        }        public EncodeSessionState SessionState         {            get;            set;        }        public EncodeSession Session        {            get            {                return _encodeSession;            }            set            {                _encodeSession = value;            }        }        /// <summary>        /// 编码对象所在用户控件对象        /// </summary>        public UserControl OwnPage        {            get            {                return _page;            }            set            {                _page = value;            }        }        /// <summary>        /// 捕获源        /// </summary>        public CaptureSource Source        {            get            {                return _cSource;            }        }        /// <summary>        ///  *** 作音频对象        /// </summary>        public AudioSinkExtensions AudioSink        {            get            {                return _audioSink;            }        }        public static VIDeoCaptureDevice DefaultVIDeoDevice        {            get            {                return CaptureDeviceConfiguration.GetDefaultVIDeoCaptureDevice();            }        }                public static ReadonlyCollection<VIDeoCaptureDevice> AvailableVIDeoDevice        {            get            {                return CaptureDeviceConfiguration.GetAvailableVIDeoCaptureDevices();            }        }        public VIDeoCaptureDevice VIDeoDevice        {            get;            set;        }        public static AudioCaptureDevice DefaultAudioDevice        {            get            {                return CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();            }        }        public static ReadonlyCollection<AudioCaptureDevice> AvailableAudioDevice        {            get            {                return CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();            }        }        public AudioCaptureDevice AudioDevice        {            get;            set;        }        private Object lockObj = new object();        internal VIDeoinputFormatInfo vIDeoinputFormatInfo;        internal AudioinputFormatInfo audioinputFormatInfo;        internal VIDeoOutputFormatInfo vIDeoOutputFormatInfo;        internal AudioOutputFormatInfo audioOutputFormatInfo;        internal OutputContainerInfo outputContainerInfo;        /// <summary>        /// 视频录制        /// </summary>        public voID StartRecord()        {            lock (lockObj)            {                if (this.SessionState == EncodeSessionState.Stop)                {                    _vIDeosink = new VIDeosinkExtensions(this);                    _audioSink = new AudioSinkExtensions(this);                    //_audioSink.VolumnChange += new AudioSinkExtensions.VolumnChangeHanlder(_audioSink_VolumnChange);                    if (_encodeSession == null)                    {                        _encodeSession = new EncodeSession();                    }                    PrepareFormatInfo(_cSource.VIDeoCaptureDevice.DesiredFormat,_cSource.AudioCaptureDevice.DesiredFormat);                    _encodeSession.Prepare(vIDeoinputFormatInfo,audioinputFormatInfo,vIDeoOutputFormatInfo,audioOutputFormatInfo,outputContainerInfo);                    _encodeSession.Start(false,200);                    this.SessionState = EncodeSessionState.Start;                }            }        }        /// <summary>        /// 音量大小指示        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        //voID _audioSink_VolumnChange(object sender,VolumnChangeArgs e)        //{        //    this.OwnPage.dispatcher.BeginInvoke(new Action(() =>        //    {        //        (        //            this.OwnPage.Tag as Progressbar).Value = e.Volumn;        //    }));        //}        /// <summary>        /// 暂停录制        /// </summary>        public voID PauseRecord()        {            lock (lockObj)            {                this.SessionState = EncodeSessionState.Pause;                _encodeSession.Pause();            }        }        /// <summary>        /// 停止录制        /// </summary>        public voID StopRecord()        {            lock (lockObj)            {                this.SessionState = EncodeSessionState.Stop;                _encodeSession.Shutdown();                _vIDeosink = null;                _audioSink = null;            }        }        /// <summary>        /// 准备编码信息        /// </summary>        /// <param name="vIDeoFormat"></param>        /// <param name="audioFormat"></param>        private voID PrepareFormatInfo(VIDeoFormat vIDeoFormat,AudioFormat audioFormat)        {            uint FrameRateratioNumerator = 0;            uint FrameRaterationDenominator = 0;            FormatConstants.FrameRatetoRatio((float)Math.Round(vIDeoFormat.FramesPerSecond,2),ref FrameRateratioNumerator,ref FrameRaterationDenominator);            vIDeoinputFormatInfo.FrameRateratioNumerator = FrameRateratioNumerator;            vIDeoinputFormatInfo.FrameRateratioDenominator = FrameRaterationDenominator;            vIDeoinputFormatInfo.FrameWIDthInPixels = _vIDeoWIDth;            vIDeoinputFormatInfo.FrameHeightInPixels = _vIDeoHeight ;            vIDeoinputFormatInfo.StrIDe = (int)_vIDeoWIDth*-4;            vIDeoOutputFormatInfo.FrameRateratioNumerator = FrameRateratioNumerator;            vIDeoOutputFormatInfo.FrameRateratioDenominator = FrameRaterationDenominator;            vIDeoOutputFormatInfo.FrameWIDthInPixels = vIDeoOutputFormatInfo.FrameWIDthInPixels == 0 ? (uint)vIDeoFormat.PixelWIDth : vIDeoOutputFormatInfo.FrameWIDthInPixels;            vIDeoOutputFormatInfo.FrameHeightInPixels = vIDeoOutputFormatInfo.FrameHeightInPixels == 0 ? (uint)vIDeoFormat.PixelHeight : vIDeoOutputFormatInfo.FrameHeightInPixels;            audioinputFormatInfo.BitsPerSample = (uint)audioFormat.BitsPerSample;            audioinputFormatInfo.SamplesPerSecond = (uint)audioFormat.SamplesPerSecond;            audioinputFormatInfo.ChannelCount = (uint)audioFormat.Channels;            if (outputContainerInfo.filePath == null || outputContainerInfo.filePath == string.Empty)            {                _saveFullPath=System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyVIDeos),"cCameraRecordVIDeo.tmp");            }            outputContainerInfo.filePath = _saveFullPath;            //outputContainerInfo.filePath = _saveFullPath;            if (audioOutputFormatInfo.AverageBitrate == 0)                audioOutputFormatInfo.AverageBitrate = 24000;            if (vIDeoOutputFormatInfo.AverageBitrate == 0)                vIDeoOutputFormatInfo.AverageBitrate = 2000000;        }        /// <summary>        /// 开始捕获        /// </summary>        public voID StartCaptrue()        {            if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())            {                _cSource.Start();            }        }        /// <summary>        /// 停止捕获        /// </summary>        public voID StopCapture()        {            _vIDeosink = null;            _audioSink = null;            _cSource.Stop();        }        /// <summary>        /// 获得视频        /// </summary>        /// <returns></returns>        public VIDeoBrush GetVIDeoBrush()        {            VIDeoBrush vBrush = new VIDeoBrush();            vBrush.SetSource(_cSource);            return vBrush;        }        /// <summary>        /// 获得视频        /// </summary>        /// <returns></returns>        public Rectangle GetVIDeoRectangle()        {            Rectangle rctg = new Rectangle();            rctg.WIDth = this._vIDeoWIDth;            rctg.Height = this._vIDeoHeight;            rctg.Fill = GetVIDeoBrush();            return rctg;        }        /// <summary>        /// 保存视频        /// </summary>        public voID SaveRecord()        {            if (_saveFullPath == string.Empty)            {                MessageBox.Show("尚未录制视频,无法进行保存!","系统提示",MessageBoxbutton.OK);                return;            }            SavefileDialog sfd = new SavefileDialog            {                Filter = "MP4 files (*.mp4)|*.mp4",DefaultExt = ".mp4",FilterIndex = 1            };            if ((bool)sfd.ShowDialog())            {                using (Stream stm=sfd.Openfile())                {                    fileStream fs = new fileStream(_saveFullPath,fileMode.Open,fileAccess.Read);                    try                    {                        byte[] buffur = new byte[fs.Length];                        fs.Read(buffur,(int)fs.Length);                        stm.Write(buffur,(int)buffur.Length);                        fs.Close();                        file.Delete(_saveFullPath);                    }                    catch (IOException ioe)                    {                        MessageBox.Show("文件保存失败!错误信息如下:"+Environment.Newline+ioe.Message,MessageBoxbutton.OK);                    }                    stm.Close();                }            }        }    }}

当然上面说过必须有两个Sink:

[csharp] view plain copy print ? using System;   using System.windows.Media;   using System.windows.Controls;   using Microsoft.Silverlight.windows.LocalEncode;      namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa   {       public class VIDeosinkExtensions:VIDeosink       {           //private UserControl _page;           //private EncodeSession _session;           private LocalCamera _localCamera;           public VIDeosinkExtensions(LocalCamera localCamera)           {               //this._page = page;               this._localCamera = localCamera;               //this._session = session;               this.CaptureSource = _localCamera.source;           }              protected overrIDe voID OnCaptureStarted()           {                          }              protected overrIDe voID OnCaptureStopped()           {              }              protected overrIDe voID OnFormatChange(VIDeoFormat vIDeoFormat)           {              }              protected overrIDe voID OnSample(long sampleTimeInHundrednanoseconds, long frameDurationInHundrednanoseconds, byte[] sampleData)           {               if (_localCamera.SessionState == EncodeSessionState.Start)               {                   _localCamera.OwnPage.dispatcher.BeginInvoke(new Action<longlongbyte[]>((ts, dur, data) =>                   {                       _localCamera.Session.WriteVIDeoSample(data, data.Length, ts, dur);                   }), sampleTimeInHundrednanoseconds, frameDurationInHundrednanoseconds, sampleData);               }           }       }   }  
using System;using System.windows.Media;using System.windows.Controls;using Microsoft.Silverlight.windows.LocalEncode;namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa{    public class VIDeosinkExtensions:VIDeosink    {        //private UserControl _page;        //private EncodeSession _session;        private LocalCamera _localCamera;        public VIDeosinkExtensions(LocalCamera localCamera)        {            //this._page = page;            this._localCamera = localCamera;            //this._session = session;            this.CaptureSource = _localCamera.source;        }        protected overrIDe voID OnCaptureStarted()        {                    }        protected overrIDe voID OnCaptureStopped()        {        }        protected overrIDe voID OnFormatChange(VIDeoFormat vIDeoFormat)        {        }        protected overrIDe voID OnSample(long sampleTimeInHundrednanoseconds,long frameDurationInHundrednanoseconds,byte[] sampleData)        {            if (_localCamera.SessionState == EncodeSessionState.Start)            {                _localCamera.OwnPage.dispatcher.BeginInvoke(new Action<long,long,byte[]>((ts,dur,data) =>                {                    _localCamera.Session.WriteVIDeoSample(data,data.Length,ts,dur);                }),sampleTimeInHundrednanoseconds,frameDurationInHundrednanoseconds,sampleData);            }        }    }}
[csharp] view plain copy print ? using System;   using System.windows.Media;   using System.windows.Controls;   using Microsoft.Silverlight.windows.LocalEncode;         namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa   {       public class AudioSinkExtensions:AudioSink       {           private LocalCamera _localCamera;           public AudioSinkExtensions(LocalCamera localCamera)           {               this._localCamera = localCamera;               this.CaptureSource = _localCamera.source;              }           protected overrIDe voID OnCaptureStarted()           {                          }              protected overrIDe voID OnCaptureStopped()           {              }              protected overrIDe voID OnFormatChange(AudioFormat audioFormat)           {              }              protected overrIDe voID OnSamples(long sampleTimeInHundrednanoseconds, long sampleDurationInHundrednanoseconds, byte[] sampleData)           {               if (_localCamera.SessionState == EncodeSessionState.Start)               {                   _localCamera.OwnPage.dispatcher.BeginInvoke(new Action<long, data) =>                   {                       _localCamera.Session.WriteAudioSample(data, dur);                   }), sampleDurationInHundrednanoseconds, sampleData);                      //计算音量变化                   //for (int index = 0; index < sampleData.Length; index += 1)                   //{                   //    short sample = (short)((sampleData[index] << 8) | sampleData[index]);                   //    float sample32 = sample / 32768f;                   //    float maxValue = 0;                   //    float minValue = 0;                   //    maxValue = Math.Max(maxValue, sample32);                   //    minValue = Math.Min(minValue, sample32);                   //    float lastPeak = Math.Max(maxValue, Math.Abs(minValue));                   //    float micLevel = (100 - (lastPeak * 100)) * 10;                   //    OnVolumnChange(this, new VolumnChangeArgs() { Volumn=micLevel});                   //}               }           }                 /// <summary>           /// 定义一个事件,反馈音量变化           /// </summary>           /// <param name="sender"></param>           /// <param name="e"></param>           //public delegate voID VolumnChangeHanlder(object sender, VolumnChangeArgs e);           //public event VolumnChangeHanlder VolumnChange;           //private voID OnVolumnChange(object sender, VolumnChangeArgs e)           //{           //    if (VolumnChange != null)           //    {           //        VolumnChange(sender, e);           //    }           //}       }          //public class VolumnChangeArgs : EventArgs       //{       //    public float Volumn       //    {       //        get;       //        internal set;       //    }       //}   }  
using System;using System.windows.Media;using System.windows.Controls;using Microsoft.Silverlight.windows.LocalEncode;namespace Cmj.MyWeb.MySilverlight.SilverlightmeIDa{    public class AudioSinkExtensions:AudioSink    {        private LocalCamera _localCamera;        public AudioSinkExtensions(LocalCamera localCamera)        {            this._localCamera = localCamera;            this.CaptureSource = _localCamera.source;        }        protected overrIDe voID OnCaptureStarted()        {                    }        protected overrIDe voID OnCaptureStopped()        {        }        protected overrIDe voID OnFormatChange(AudioFormat audioFormat)        {        }        protected overrIDe voID OnSamples(long sampleTimeInHundrednanoseconds,long sampleDurationInHundrednanoseconds,data) =>                {                    _localCamera.Session.WriteAudioSample(data,sampleDurationInHundrednanoseconds,sampleData);                //计算音量变化                //for (int index = 0; index < sampleData.Length; index += 1)                //{                //    short sample = (short)((sampleData[index] << 8) | sampleData[index]);                //    float sample32 = sample / 32768f;                //    float maxValue = 0;                //    float minValue = 0;                //    maxValue = Math.Max(maxValue,sample32);                //    minValue = Math.Min(minValue,sample32);                //    float lastPeak = Math.Max(maxValue,Math.Abs(minValue));                //    float micLevel = (100 - (lastPeak * 100)) * 10;                //    OnVolumnChange(this,new VolumnChangeArgs() { Volumn=micLevel});                //}            }        }        /// <summary>        /// 定义一个事件,反馈音量变化        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        //public delegate voID VolumnChangeHanlder(object sender,VolumnChangeArgs e);        //public event VolumnChangeHanlder VolumnChange;        //private voID OnVolumnChange(object sender,VolumnChangeArgs e)        //{        //    if (VolumnChange != null)        //    {        //        VolumnChange(sender,e);        //    }        //}    }    //public class VolumnChangeArgs : EventArgs    //{    //    public float Volumn    //    {    //        get;    //        internal set;    //    }    //}}

有了这三个类,下面准备一个界面,使用LocalCamera进行视频录制 *** 作。

需要注意的是保存 *** 作,事实上在EncodeSession中视频的保存路径是在视频录制之前就必须指定的(当然这一点并不难理解,因为长时间的视频录制是会形成很大的文件的,保存之前缓存到内存中也不是很现实),在LocalCamera中对保存方法的封装事实上是文件的读取和删除 *** 作。另外在这个例子中用到了前面文章中自定义的OOB控件,不明白的朋友可以查看前面的文章内容。下面是调用代码:

[csharp] view plain copy print ? using System;   using System.Collections.Generic;   using System.linq;   using System.Net;   using System.windows;   using System.windows.Controls;   using System.windows.documents;   using System.windows.input;   using System.windows.Media;   using System.windows.Media.Animation;   using System.windows.Shapes;   using System.windows.Threading;   using Cmj.MyWeb.MySilverlight.SiverlightOOB;   using Cmj.MyWeb.MySilverlight.SilverlightmeIDa;      namespace SilverlightVIDeoRecord   {       public partial class MainPage : UserControl       {           public MainPage()           {               InitializeComponent();           }              OOBInstall install = new OOBInstall();           LocalCamera localCamera = null;           dispatcherTimer timer = null;           private DateTime startTime = DateTime.Now;           private voID UserControl_Loaded(object sender, RoutedEventArgs e)           {               timer = new dispatcherTimer();               timer.Interval = TimeSpan.FromSeconds(1);               timer.Tick += new EventHandler(timer_Tick);               if (install.IsRunOutOfbrowser)               {                   this.btnInstall.Visibility = Visibility.Collapsed;                   localCamera = new LocalCamera(this,LocalCamera.AvailableVIDeoDevice[1].SupportedFormats[0],LocalCamera.DefaultAudioDevice.SupportedFormats[1]);                   this.bdVIDeo.Child = localCamera.GetVIDeoRectangle();                   //this.Tag = this.pbVolumn;               }               else               {                   this.btnInstall.Visibility = Visibility.Visible;                   this.btnStart.IsEnabled = false;                   this.btnPause.IsEnabled = false;                   this.btnStop.IsEnabled = false;                   this.btnSave.IsEnabled = false;                   //this.tbTitlebar.IsEnabled = false;                   //this.rbResizebutton.IsEnabled = false;               }           }              voID timer_Tick(object sender, EventArgs e)           {               TimeSpan tsstart = new TimeSpan(startTime.Ticks);               TimeSpan tsEnd = new TimeSpan(DateTime.Now.Ticks);               TimeSpan tsTract = tsEnd.Subtract(tsstart);               DateTime timeInterval = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, tsTract.Hours, tsTract.Minutes, tsTract.Seconds);               //this.txtblkTimer.Text = string.Format("{0}:{1}:{2}",tsTract.Minutes,tsTract.Seconds);               this.txtblkTimer.Text = timeInterval.TolongTimeString();           }              private voID btnStart_Click(object sender, RoutedEventArgs e)           {               localCamera.StartCaptrue();//启动视频捕获           }              private voID btnRecord_Click(object sender, RoutedEventArgs e)           {               localCamera.StartRecord();//开始录制               this.txtblkTimer.Text = "0:00:00";               this.startTime = DateTime.Now;               timer.Start();           }              private voID btnPause_Click(object sender, RoutedEventArgs e)           {               localCamera.PauseRecord();//暂停录制               timer.Stop();           }              private voID btnStop_Click(object sender, RoutedEventArgs e)           {               localCamera.StopRecord();//停止录制               localCamera.StopCapture();//停止视频捕获               timer.Stop();           }              private voID btnSave_Click(object sender, RoutedEventArgs e)           {               localCamera.SaveRecord();//保存视频           }              private voID btnInstall_Click(object sender, RoutedEventArgs e)           {               install.Install();           }       }   }  
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.windows.Threading;using Cmj.MyWeb.MySilverlight.SiverlightOOB;using Cmj.MyWeb.MySilverlight.SilverlightmeIDa;namespace SilverlightVIDeoRecord{    public partial class MainPage : UserControl    {        public MainPage()        {            InitializeComponent();        }        OOBInstall install = new OOBInstall();        LocalCamera localCamera = null;        dispatcherTimer timer = null;        private DateTime startTime = DateTime.Now;        private voID UserControl_Loaded(object sender,RoutedEventArgs e)        {            timer = new dispatcherTimer();            timer.Interval = TimeSpan.FromSeconds(1);            timer.Tick += new EventHandler(timer_Tick);            if (install.IsRunOutOfbrowser)            {                this.btnInstall.Visibility = Visibility.Collapsed;                localCamera = new LocalCamera(this,LocalCamera.DefaultAudioDevice.SupportedFormats[1]);                this.bdVIDeo.Child = localCamera.GetVIDeoRectangle();                //this.Tag = this.pbVolumn;            }            else            {                this.btnInstall.Visibility = Visibility.Visible;                this.btnStart.IsEnabled = false;                this.btnPause.IsEnabled = false;                this.btnStop.IsEnabled = false;                this.btnSave.IsEnabled = false;                //this.tbTitlebar.IsEnabled = false;                //this.rbResizebutton.IsEnabled = false;            }        }        voID timer_Tick(object sender,EventArgs e)        {            TimeSpan tsstart = new TimeSpan(startTime.Ticks);            TimeSpan tsEnd = new TimeSpan(DateTime.Now.Ticks);            TimeSpan tsTract = tsEnd.Subtract(tsstart);            DateTime timeInterval = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,tsTract.Hours,tsTract.Seconds);            //this.txtblkTimer.Text = string.Format("{0}:{1}:{2}",tsTract.Seconds);            this.txtblkTimer.Text = timeInterval.TolongTimeString();        }        private voID btnStart_Click(object sender,RoutedEventArgs e)        {            localCamera.StartCaptrue();//启动视频捕获        }        private voID btnRecord_Click(object sender,RoutedEventArgs e)        {            localCamera.StartRecord();//开始录制            this.txtblkTimer.Text = "0:00:00";            this.startTime = DateTime.Now;            timer.Start();        }        private voID btnPause_Click(object sender,RoutedEventArgs e)        {            localCamera.PauseRecord();//暂停录制            timer.Stop();        }        private voID btnStop_Click(object sender,RoutedEventArgs e)        {            localCamera.StopRecord();//停止录制            localCamera.StopCapture();//停止视频捕获            timer.Stop();        }        private voID btnSave_Click(object sender,RoutedEventArgs e)        {            localCamera.SaveRecord();//保存视频        }        private voID btnInstall_Click(object sender,RoutedEventArgs e)        {            install.Install();        }    }}

OK,下面是视频录制的截图:

正在录制

 

停止录制后保存

播放录制的视频

三、注意:

1.vIDeo sink和audio sink都是运行在不同于UI的各自的线程中,你可以使用UI的dispathcher或者SynchronizationContext进行不同线程之间的调用。

2.在vIDeo sink和audio sink的OnSample方法中必须进行状态判断,因为sink实例创建之后就会执行OnSample方法,但此时EncodeSession还没有启动因此如果不进行状态判读就会抛出com异常。

3.视频的宽度和高度不能够随意指定,这个在nesL的帮助文档中也是特意说明的,如果任意指定同样会抛出异常。

4.最后再次提醒大家,上面的视频录制是基于nesL的因此必须将应用运行到浏览器外(OOB)。

源代码下载

作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,演绎或用于商业目的。但转载请注明来自崔江涛(KenshinCui),并包含相关链接。
总结

以上是内存溢出为你收集整理的Silverlight之视频录制全部内容,希望文章能够帮你解决Silverlight之视频录制所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1022842.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存