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, 0, ( int )buffur.Length);
fs.Close();
File.Delete(_saveFullPath);
}
catch (IOException ioe)
{
MessageBox.Show( "文件保存失败!错误信息如下:" +Environment.NewLine+ioe.Message, "系统提示" ,MessageBoxButton.OK);
}
stm.Close();
}
}
}
}
}
|