zoukankan      html  css  js  c++  java
  • EasyPlayerPro windows播放器本地音频播放音量控制实现

    背景描述

    作为一个播放器, 除了能播放视频和声音外,音量控制是绝对不能缺少的功能; 本文在音视频播放的基础上,增加对音量的控制;

    EasyPlayerPro播放器

    实现流程

    • 调用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
    ", 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
    ", mmhr);
    }
    mixerClose(hMixer);
    
    _TRACE(TRACE_LOG_DEBUG, "GetVolume: %d
    ", 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
    ", 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

    技术支持

    获取更多信息

    EasyDarwin开源流媒体服务器:www.EasyDarwin.org

    EasyDSS商用流媒体解决方案:www.EasyDSS.com

    EasyNVR无插件直播方案:www.EasyNVR.com

    Copyright © EasyDarwin Team 2012-2017

    EasyDarwin

  • 相关阅读:
    Java中返回参数值的几种状态
    Java中的二维数组
    Java foreach操作(遍历)数组
    Arrays 类操作 Java 的数组排序
    Java循环语句 for
    Java循环语句 while
    Java条件语句 switch case
    Java多重if....else if
    margin优化的一种思路
    5.命名规则
  • 原文地址:https://www.cnblogs.com/babosa/p/8206957.html
Copyright © 2011-2022 走看看