EasyPlayerPro-win音量控制实现
来源:互联网 发布:培训机构网络推广方案 编辑:程序博客网 时间:2024/05/17 20:30
EasyPlayerPro-win音量控制实现
背景描述
作为一个播放器, 除了能播放视频和声音外,音量控制是绝对不能缺少的功能; 本文在音视频播放的基础上,增加对音量的控制;
实现流程
调用mixerGetDevCaps获取音频输出设备列表;
打开指定的音频输出设备;
获取指定音频输出设备的音频属性;
获取和设置音量;
DWORD GetVolume();int SetVolume(DWORD vol);int Init(DWORD ComponentType,int *min,int *max);int GetAudioOutputDeviceList(MIXER_DEVICE_INFO_T **devicelist, int *deviceNum);int SetAudioDeviceId(int _deviceIdx);
代码实现
//获取音频输出设备列表int CVolumeControl::GetAudioOutputDeviceList(MIXER_DEVICE_INFO_T **devicelist, int *deviceNum){int idx = 0;if (mDeviceNum < 1){ MIXERCAPS mxcaps; UINT cMixerDevs = mixerGetNumDevs(); for (UINT iDevIndex = 0; iDevIndex < cMixerDevs && iDevIndex<MAX_MIXER_DEVICE_NUM; iDevIndex++) { mixerGetDevCaps(iDevIndex, &mxcaps, sizeof(mxcaps)); mixerDeviceList[iDevIndex].id = iDevIndex; strcpy(mixerDeviceList[iDevIndex].name, mxcaps.szPname); } mDeviceNum = cMixerDevs;}if (NULL != deviceNum) *deviceNum = mDeviceNum;if (NULL != devicelist) *devicelist = &mixerDeviceList[0];return 0;}//获取音量DWORD CVolumeControl::GetVolume(){int devIdx = mDeviceId;if (devIdx < 0) return -1;HMIXER hMixer;MMRESULT mmhr;mmhr = mixerOpen(&hMixer, devIdx, 0, 0, MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_DESTINATION);if( mmhr != MMSYSERR_NOERROR ){ _TRACE(TRACE_LOG_ERROR, "GetVolume::mixerOpen fail. %d\n", mmhr); return 0;}MIXERCAPS tmixercaps;if( mixerGetDevCaps( devIdx, &tmixercaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR ) { mixerClose(hMixer); return -1;}bool ffind = false;MIXERLINE mxline;for(int i = 0; i < (int)tmixercaps.cDestinations; i++ ) { ZeroMemory( &mxline, sizeof(MIXERLINE) ); mxline.cbStruct = sizeof(MIXERLINE); mxline.dwDestination = i; mmhr = ::mixerGetLineInfo( (HMIXEROBJ)hMixer, &mxline, MIXER_OBJECTF_HMIXER);// | MIXER_GETLINEINFOF_COMPONENTTYPE ); if( mmhr != MMSYSERR_NOERROR ) { continue; } else { if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_DIGITAL ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } else if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_MONITOR ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } else if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } }}MIXERCONTROL mxcWaveoutMux;memset(&mxcWaveoutMux, 0x00, sizeof(MIXERCONTROL)); _GetLineControls( hMixer, mxline, &mxcWaveoutMux, NULL, NULL );MIXERCONTROLDETAILS mxcd;MIXERCONTROLDETAILS_UNSIGNED mxdu;memset(&mxdu, 0x00, sizeof(MIXERCONTROLDETAILS_UNSIGNED));mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);mxcd.cMultipleItems = 0; mxcd.cChannels = mxline.cChannels;mxcd.dwControlID = mxcWaveoutMux.dwControlID;mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);mxcd.paDetails = &mxdu;mmhr = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE);if( mmhr != MMSYSERR_NOERROR ){ _TRACE(TRACE_LOG_ERROR, "GetVolume::mixerGetControlDetails fail. %d\n", mmhr);}mixerClose(hMixer);_TRACE(TRACE_LOG_DEBUG, "GetVolume: %d\n", mxdu.dwValue);return mxdu.dwValue;}//设置音量int CVolumeControl::SetVolume(DWORD vol){int devIdx = mDeviceId;if (devIdx < 0) return -1;HMIXER hMixer;MMRESULT mmhr;mmhr = mixerOpen(&hMixer, 0, 0, 0, 0);if (mmhr!= MMSYSERR_NOERROR){ _TRACE(TRACE_LOG_ERROR, "mixerOpen fail. %d\n", mmhr); return -1;}MIXERCAPS tmixercaps;if( mixerGetDevCaps( devIdx, &tmixercaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR ) { mixerClose(hMixer); return -1;}bool ffind = false;MIXERLINE mxline;for(int i = 0; i < (int)tmixercaps.cDestinations; i++ ) { ZeroMemory( &mxline, sizeof(MIXERLINE) ); mxline.cbStruct = sizeof(MIXERLINE); mxline.dwDestination = i; mmhr = ::mixerGetLineInfo( (HMIXEROBJ)hMixer, &mxline, MIXER_OBJECTF_HMIXER);// | MIXER_GETLINEINFOF_COMPONENTTYPE ); if( mmhr != MMSYSERR_NOERROR ) { continue; } else { // if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_DIGITAL ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } else if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_MONITOR ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } else if( mxline.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ) { if( 0 != (MIXERLINE_LINEF_ACTIVE & mxline.fdwLine) ) { ffind = true; break; } } }}MIXERCONTROL mxcWaveoutMux;memset(&mxcWaveoutMux, 0x00, sizeof(MIXERCONTROL)); _GetLineControls( hMixer, mxline, &mxcWaveoutMux, NULL, NULL );int ret = 0;MIXERCONTROLDETAILS mxcd;MIXERCONTROLDETAILS_UNSIGNED mxdu;memset(&mxdu, 0x00, sizeof(MIXERCONTROLDETAILS_UNSIGNED));mxdu.dwValue = vol;mxcd.cMultipleItems = 0; mxcd.cChannels = mxline.cChannels;mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);mxcd.dwControlID = mxcWaveoutMux.dwControlID;mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);mxcd.paDetails = &mxdu;mmhr = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER); if (mmhr != MMSYSERR_NOERROR){ ret = -1;}mixerClose(hMixer);return ret;}
关于EasyPlayerPro
EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放、倍数播放等多种功能特性,核心基于ffmpeg,稳定、高效、可靠、可控,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!
EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro
点击链接加入群【EasyPlayer & EasyPlayerPro】:544917793
技术支持
邮件:support@easydarwin.org
QQ交流群:544917793
EasyPlayerPro是一款非常稳定的全协议/全功能播放器组件,可以通过以上渠道进行更深入的技术与合作咨询;
获取更多信息
EasyDarwin开源流媒体服务器:www.EasyDarwin.org
EasyDSS商用流媒体解决方案:www.EasyDSS.com
EasyNVR无插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2017
阅读全文