日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > [C#] 控制系統音量-第二章

[C#] 控制系統音量-第二章

來源:程序員人生   發布時間:2014-12-23 08:50:09 閱讀次數:3277次

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請注明出處:http://blog.csdn.net/qiujuer/article/details/41575517

========================================================

引入

在很久之前寫了1篇 [C#] 控制系統音量-第1章 ,忘記是甚么時候寫的了;不過并沒有忘記有這回事兒,不過看見沒有甚么人需要所以就沒有出后面的文章了。前天突然看見評論有人需要,所以覺得有必要完善1下;總結了1下這是第2章,同時也是終章;之前準備寫多章仔細分析1下的,現在看來就介紹1下如何使用吧。

問題

在第1章中,控制電腦音量是能夠實現的,但是只支持XP系統;這無疑是糟的;現在這個階段使用XP的還有多少?本篇為支持Win7及其以上版本音量控制而生。

兼容性(C#)

Win7、Win8、Win8.1

前戲

在開始之前有必要介紹1下 Core Audio APIs ,甚么是 Core Audio APIsCore Audio APIs 是微軟在WIn7以后提供的1套用于控制系統音量的Api,其具有以下特點:

  1. 低延時,幾近無故障的音頻流。
  2. 提高可靠性 ( 很多音頻函數從核心態移到了用戶態 )
  3. 提高了安全性 (在安全的,低優先級別的線程處理被保護的音頻內容)
  4. 分配了特定的系統級別的規則 (console, multimedia, communications) 給單獨的音頻裝備。
  5. 用戶可以直接操作,相應 endpoint 裝備的軟件抽象 ( 如:擴音器,耳麥及麥克風 ) 以下的高層 API 是以 Core Audio APIs 來工作的。

相干介紹:

http://msdn.microsoft.com/en-us/library/dd370802(VS.85).aspx

http://msdn.microsoft.com/en-us/library/dd370784(v=vs.85).aspx

固然這里我們其實不是直接使用此API,由于其是C++的調用接口,在這里對其進行了封裝,封裝成C#下能直接調用的dll文件;后面添加。

CoreAudioApi.dll 包結構:


在這里就不詳細介紹其中代碼,打包時會同時把 CoreAudioApi.pdb 文件打包,在調試時能進入其中查看代碼。

至于導入 DLL 到項目中,這個也無需說了吧。

CodeTime

在這里還要進行1次簡單的調用簡化封裝,封裝為 VolumeControl class.

VolumeControl.cs

namespace Volume { public class VolumeControl { private static VolumeControl _VolumeControl; private MMDevice device; public event AudioNotificationDelegate OnAudioNotification; public bool InitializeSucceed; public static VolumeControl Instance { get { if (_VolumeControl == null) _VolumeControl = new VolumeControl(); return _VolumeControl; } } private VolumeControl() { MMDeviceEnumerator DevEnum = new MMDeviceEnumerator(); try { device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia); device.AudioEndpointVolume.OnVolumeNotification += new AudioEndpointVolumeNotificationDelegate(AudioEndpointVolume_OnVolumeNotification); InitializeSucceed = true; } catch { InitializeSucceed = false; } } private void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data) { if (InitializeSucceed && this.OnAudioNotification != null) { this.OnAudioNotification(null, new AudioNotificationEventArgs() { MasterVolume = data.MasterVolume * 100, Muted = data.Muted }); } } public double MasterVolume { get { return InitializeSucceed ? device.AudioEndpointVolume.MasterVolumeLevelScalar * 100 : 0; } set { if (InitializeSucceed) { device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)(value / 100.0f); if (this.IsMute) this.IsMute = false; } } } public bool IsMute { get { return InitializeSucceed ? device.AudioEndpointVolume.Mute : true; } set { if (InitializeSucceed)device.AudioEndpointVolume.Mute = value; } } public double[] AudioMeterInformation { get { if (InitializeSucceed) { try { return new double[3]{ device.AudioMeterInformation.MasterPeakValue * 100.00, device.AudioMeterInformation.PeakValues[0] * 100, device.AudioMeterInformation.PeakValues[1] * 100 }; } catch { return new double[3] { 0, 0, 0 }; } } else return new double[3] { 0, 0, 0 }; } } } public delegate void AudioNotificationDelegate(object sender, AudioNotificationEventArgs e); public class AudioNotificationEventArgs : EventArgs { public double MasterVolume { get; set; } public bool Muted { get; set; } } }
可以看到,在代碼中為了外面調用的方便性,我們采取了單列模式,固然這里沒有單獨對多線程添加鎖的機制??勺孕刑砑悠? Instance 部份。

其中有4個變量:

  • VolumeControl 固然是為了單列而生的
  • MMDevice 實際的音量操作,來自于封裝了1次的 CoreAudioApi.dll
  • AudioNotificationDelegate 可以看見最后面的地方實際上是1個事件拜托,用于事件的通知,主要作用是當系統音量改變時通知主界面進行刷新界面
  • InitializeSucceed 這個是用于記錄是不是初始化成功的參數;固然可以去掉

static VolumeControl Instance 用于保證單列的運行

在類的構造函數中,可以看到:

MMDeviceEnumerator DevEnum = new MMDeviceEnumerator(); device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia); device.AudioEndpointVolume.OnVolumeNotification += new AudioEndpointVolumeNotificationDelegate(AudioEndpointVolume_OnVolumeNotification);
其中 實例化了1個 MMDeviceEnumerator 類,然后初始化了 MMDevice 屬性;同時在這里進行了注冊事件,讓音量改變時調用方法 AudioEndpointVolume_OnVolumeNotification()

而在方法 AudioEndpointVolume_OnVolumeNotification() 中又調用了當前類的拜托事件,用于觸發事件刷新界面;同時對傳遞的參數進行了封裝;封裝為了類:AudioNotificationEventArgs

在類 AudioNotificationEventArgs 中:

public class AudioNotificationEventArgs : EventArgs { public double MasterVolume { get; set; } public bool Muted { get; set; } }
包括兩個屬性,分別是當前音量大小和是不是靜音。

繼續分析我們的主類:

public double MasterVolume { get { return InitializeSucceed ? device.AudioEndpointVolume.MasterVolumeLevelScalar * 100 : 0; } set { if (InitializeSucceed) { device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)(value / 100.0f); if (this.IsMute) this.IsMute = false; } } } public bool IsMute { get { return InitializeSucceed ? device.AudioEndpointVolume.Mute : true; } set { if (InitializeSucceed)device.AudioEndpointVolume.Mute = value; } }
這兩個屬性,分別用于設置與獲得當前主音量大小和是不是靜音操作的封裝。

public double[] AudioMeterInformation { get { if (InitializeSucceed) { try { return new double[3]{ device.AudioMeterInformation.MasterPeakValue * 100.00, device.AudioMeterInformation.PeakValues[0] * 100, device.AudioMeterInformation.PeakValues[1] * 100 }; } catch { return new double[3] { 0, 0, 0 }; } } else return new double[3] { 0, 0, 0 }; } }
該方法用于獲得當前的音量信息,分別是主音量、左聲道右聲道。

ViewCode

在這里使用WPF作為示例,界面代碼:

<Grid Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel> <Label Content="音量" /> <Label Content="主聲道:" Margin="0,10,0,0"/> <ProgressBar x:Name="mMasterPBar" Minimum="0" Maximum="100" Width="170" HorizontalAlignment="Right" Margin="0,0,10,0"/> <Label Content="左聲道:" Margin="0,10,0,0"/> <ProgressBar x:Name="mLeftPBar" Minimum="0" Maximum="100" Width="170" HorizontalAlignment="Right" Margin="0,0,10,0"/> <Label Content="右聲道:" Margin="0,10,0,0"/> <ProgressBar x:Name="mRightPBar" Minimum="0" Maximum="100" Width="170" HorizontalAlignment="Right" Margin="0,0,10,0"/> <Label Content="操作:" Margin="0,20,0,0" HorizontalAlignment="Right" /> </StackPanel> <Slider Grid.Column="1" Name="mMasterVolumeSlider" Orientation="Vertical" Height="200" Maximum="100" ValueChanged="mMasterVolumeSlider_ValueChanged" /> </Grid>

對應的界面:


界面代碼:

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeAudioControl(); } private void Page_Loaded(object sender, RoutedEventArgs e) { volumeControlTimer.Start(); } private void Page_Unloaded(object sender, RoutedEventArgs e) { volumeControlTimer.Stop(); } private VolumeControl volumeControl; private bool isUserChangeVolume = true; private DispatcherTimer volumeControlTimer; private void InitializeAudioControl() { volumeControl = VolumeControl.Instance; volumeControl.OnAudioNotification += volumeControl_OnAudioNotification; volumeControl_OnAudioNotification(null, new AudioNotificationEventArgs() { MasterVolume = volumeControl.MasterVolume }); volumeControlTimer = new DispatcherTimer(); volumeControlTimer.Interval = TimeSpan.FromTicks(150); volumeControlTimer.Tick += volumeControlTimer_Tick; } void volumeControl_OnAudioNotification(object sender, AudioNotificationEventArgs e) { this.isUserChangeVolume = false; try { this.Dispatcher.Invoke(new Action(() => { mMasterVolumeSlider.Value = e.MasterVolume; })); } catch { } this.isUserChangeVolume = true; } void volumeControlTimer_Tick(object sender, EventArgs e) { double[] information = volumeControl.AudioMeterInformation; mMasterPBar.Value = information[0]; mLeftPBar.Value = information[1]; mRightPBar.Value = information[2]; } private void mMasterVolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { if (isUserChangeVolume) { volumeControl.MasterVolume = mMasterVolumeSlider.Value; } } }

還是從屬性開始,3個屬性:

VolumeControl 這個很簡單了吧,就是上面封裝的成果

isUserChangeVolume 這個是用于排除系統回調時觸發 Slider 控件的 ValueChanged() 事件,避免無窮循環

DispatcherTimer 用于刷新界面中的音量條

開始說說方法:

InitializeAudioControl() 用于初始化 VolumeControl 同時,添加事件回調,和初始化 DispatcherTimer Timer 

volumeControl_OnAudioNotification() 回調方法

volumeControlTimer_Tick() 這個就是 DispatcherTimer 刷新界面的方法

mMasterVolumeSlider_ValueChanged() 這個就更加簡單了,界面的事件觸發方法

必要說明:

在用戶撥動界面的屬性條的時候會觸發 mMasterVolumeSlider_ValueChanged() 這時候 isUserChangeVolume True 所以能調用進行音量改變;

而當音量改變進程中(也包括用戶使用系統的音量條時)將會觸發 volumeControl_OnAudioNotification() 方法進行回調,而在 volumeControl_OnAudioNotification() 方法中,我們首先 將isUserChangeVolume = false

然后使用拜托的封裝類進行界面更改;這時候界面音量條更改必將會觸發 mMasterVolumeSlider_ValueChanged()  方法,這時候 isUserChangeVolume False 狀態,所以不會再次進行音量的更改調用,故而避免死循環狀態出現;

在最后事件觸發完后固然是把 isUserChangeVolume 重新設置為 True 了。


至于其他應當都是1看就懂了,界面加載完成時就 讓刷新線程工作,而界面 Unloaded 時自然就停止工作,避免過剩消耗。


END

附上本次的示例代碼,和 DLL 庫,都打包在1個文件夾中了。

win7 win8 C# 音量控制 Volume

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美黑人xxxx| 91精品久久久久久久99蜜桃 | 亚洲国产精品一区二区尤物区 | baoyu123成人免费看视频 | 亚洲色图偷 | 国产精品区一区二区三区 | 日韩黄色网址 | 国产精品一区一区三区 | 国内精品一区二区 | 日韩一级片毛片 | 日韩欧美专区 | 日韩av在线播放一区 | 麻豆一区二区 | 男人日女人网站 | 免费看v片 | 亚洲精品网站在线观看 | 日本一区二区三区视频在线观看 | 久久久国产精品免费 | 久久久精品久久久 | 国产在线播 | 日本福利在线观看 | 日韩在线欧美 | 国产一区二区不卡在线 | 日韩久久久久久久久久久久 | 欧美日韩亚洲天堂 | 中文字幕精品一区久久久久 | 中文字幕日韩av在线 | 99一区二区三区 | 精品成人 | 天堂中文在线网 | 亚洲国产精品麻豆 | 国产成人一区二区三区 | 国产欧美精品一区aⅴ影院 99爱在线视频 | 精品三区 | 日韩av在线免费 | 婷婷亚洲五月 | 日韩一区二区三区在线播放 | 国产精华一区二区三区 | 成年人小视频 | 在线中文av| 久久99这里只有精品 |