C++ Qt5+;如何为QMediaPlayer设置默认音频设备
我有一个使用Qt的程序,我需要让它使用用户在首选项中选择的输出设备播放声音。我可以通过调用以下代码列出windows中的所有可用设备:C++ Qt5+;如何为QMediaPlayer设置默认音频设备,c++,qt,C++,Qt,我有一个使用Qt的程序,我需要让它使用用户在首选项中选择的输出设备播放声音。我可以通过调用以下代码列出windows中的所有可用设备: QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); foreach (QAudioDeviceInfo i, devices) this->ui->comboBox->addItem(i.devi
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
foreach (QAudioDeviceInfo i, devices)
this->ui->comboBox->addItem(i.deviceName());
QList devices=QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
foreach(QAudioDeviceInfo i,设备)
此->用户界面->组合框->添加项(i.deviceName());
但是,我不知道如何更改作为应用程序默认设备的设备,以便QMediaPlayer
使用该设备播放所有声音,而不是默认设备。我该怎么做?我对仅限windows的Qt5+特定解决方案很满意,尽管跨平台解决方案可能是最好的
基本上,我希望实现类似的首选项对话框,如Microsoft Lync中的此对话框:
据微软称:Windows7引入了可以实现这一点的API。但是我不知道这是如何记录的,在哪里记录的。看起来你应该这样做(玩家是QMediaPlayer*): 您必须为创建的每个QMediaPlayer应用以下修复程序:
QMediaPlayer *player = new QMediaPlayer(this);
QMediaService *svc = player->service();
if (svc != nullptr)
{
QAudioOutputSelectorControl *out = reinterpret_cast<QAudioOutputSelectorControl*>
(svc->requestControl(QAudioOutputSelectorControl_iid));
if (out != nullptr)
{
new MFAudioEndpointControl_Fixed_Helper(out); // <- the fix; notice that it's a HELPER class
out->setActiveOutput(this->ui->comboBox->itemData(this->ui->comboBox->currentIndex()).toString()); // we have to pass deviceID, not the name
svc->releaseControl(out);
}
}
QMediaPlayer*player=新的QMediaPlayer(此);
QMediaService*svc=player->service();
如果(svc!=nullptr)
{
QAudioOutputSelectorControl*out=重新解释
(svc->requestControl(QAudioOutputSelectorControl_iid));
if(out!=nullptr)
{
新的MFAudioEndpointControl_Fixed_Helper(out);//我尝试了上面的解决方案,但不太成功。因此我将我的解决方案放在这里。它在win10上也可以正常工作(相同的方法-未记录的API):
首先添加到.pro文件:
QT += axcontainer
然后添加以下修改以适应QT头(名称:PolicyConfig.h)
mb这将帮助你@MikeMinaev我已经读过了,它没有帮助,因为它没有说明程序员如何更改默认设备的信息。我只能在Qt4中找到如何使用声子进行此操作,但QT5中没有信息根据我认为你不能更改它,我认为这是系统设置,你不能更改,但是t这是有魔力的。是的,我在上一个稳定的Qt(5.4)中也发现了这些bug://@Petr更新了答案。现在包括一个修复程序。你使用了哪种编译器?
QMediaPlayer *player = new QMediaPlayer(this);
QMediaService *svc = player->service();
if (svc != nullptr)
{
QAudioOutputSelectorControl *out = reinterpret_cast<QAudioOutputSelectorControl*>
(svc->requestControl(QAudioOutputSelectorControl_iid));
if (out != nullptr)
{
new MFAudioEndpointControl_Fixed_Helper(out); // <- the fix; notice that it's a HELPER class
out->setActiveOutput(this->ui->comboBox->itemData(this->ui->comboBox->currentIndex()).toString()); // we have to pass deviceID, not the name
svc->releaseControl(out);
}
}
QT += axcontainer
// ----------------------------------------------------------------------------
// PolicyConfig.h
// Undocumented COM-interface IPolicyConfig.
// Use for set default audio render endpoint
// @author EreTIk
// ----------------------------------------------------------------------------
#pragma once
#include "winnt.h"
//#include <QAxAggregated>
class DECLSPEC_UUID("f8679f50-850a-41cf-9c72-430f290290c8") IPolicyConfig;
class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient;
// ----------------------------------------------------------------------------
// class CPolicyConfigClient
// {870af99c-171d-4f9e-af0d-e63df40c2bc9}
//
// interface IPolicyConfig
// {f8679f50-850a-41cf-9c72-430f290290c8}
//
// Query interface:
// CComPtr<IPolicyConfig> PolicyConfig;
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigClient));
//
// @compatible: Windows 7 and Later
// ----------------------------------------------------------------------------
class IPolicyConfig : public IUnknown
{
public:
virtual HRESULT GetMixFormat(
PCWSTR,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(
PCWSTR
);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *
);
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
PCWSTR,
INT,
PINT64,
PINT64
);
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
PCWSTR,
PINT64
);
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
PCWSTR,
struct DeviceShareMode *
);
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
PCWSTR,
struct DeviceShareMode *
);
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
__in PCWSTR wszDeviceId,
__in ERole eRole
);
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
PCWSTR,
INT
);
};
class DECLSPEC_UUID("568b9108-44bf-40b4-9006-86afe5b5a620") IPolicyConfigVista;
class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") CPolicyConfigVistaClient;
// ----------------------------------------------------------------------------
// class CPolicyConfigVistaClient
// {294935CE-F637-4E7C-A41B-AB255460B862}
//
// interface IPolicyConfigVista
// {568b9108-44bf-40b4-9006-86afe5b5a620}
//
// Query interface:
// CComPtr<IPolicyConfigVista> PolicyConfig;
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigVistaClient));
//
// @compatible: Windows Vista and Later
// ----------------------------------------------------------------------------
class IPolicyConfigVista : public IUnknown
{
public:
virtual HRESULT GetMixFormat(
PCWSTR,
WAVEFORMATEX **
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *
);
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
PCWSTR,
INT,
PINT64,
PINT64
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
PCWSTR,
PINT64
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
PCWSTR,
struct DeviceShareMode *
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
PCWSTR,
struct DeviceShareMode *
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
__in PCWSTR wszDeviceId,
__in ERole eRole
);
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
PCWSTR,
INT
); // not available on Windows 7, use method from IPolicyConfig
};
#ifndef DEFAULTOUTPUT_H
#define DEFAULTOUTPUT_H
#include <QString>
#include <QHash>
class DefaultOutput
{
public:
static QHash<QString, QString> enumOutputDevices();
static bool changeOutputDevice( QString id );
};
#endif
#include <stdio.h>
#include <wchar.h>
#include <tchar.h>
#include "windows.h"
#include "Mmdeviceapi.h"
#include "PolicyConfig.h"
#include "Propidl.h"
#include "Functiondiscoverykeys_devpkey.h"
#include "defaultoutput.h"
QHash<QString, QString> DefaultOutput::enumOutputDevices()
{
QHash<QString, QString> list;
try
{
HRESULT hr = CoInitialize( NULL );
if( FAILED( hr ) )
return list;
IMMDeviceEnumerator *pEnum = NULL;
// Create a multimedia device enumerator.
hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), (void**)&pEnum );
if( FAILED( hr ) )
return list;
IMMDeviceCollection *pDevices;
// Enumerate the output devices.
hr = pEnum->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &pDevices );
if( FAILED( hr ) )
return list;
UINT count;
pDevices->GetCount(&count);
if( FAILED( hr ) )
return list;
for( UINT i = 0; i < count; i++ )
{
IMMDevice *pDevice;
hr = pDevices->Item( i, &pDevice );
if( SUCCEEDED( hr ) )
{
LPWSTR wstrID = NULL;
hr = pDevice->GetId( &wstrID );
if( SUCCEEDED( hr ) )
{
IPropertyStore* pStore;
hr = pDevice->OpenPropertyStore( STGM_READ, &pStore );
if( SUCCEEDED( hr ) )
{
PROPVARIANT friendlyName;
PropVariantInit( &friendlyName );
hr = pStore->GetValue( PKEY_Device_FriendlyName, &friendlyName );
if( SUCCEEDED( hr ) )
{
QString qid = QString::fromStdU16String( (char16_t*)wstrID );
QString qname = QString::fromStdU16String( (char16_t*)friendlyName.pwszVal );
list[qid] = qname;
PropVariantClear( &friendlyName );
}
pStore->Release();
}
}
pDevice->Release();
}
}
pDevices->Release();
pEnum->Release();
return list;
}
catch( ... )
{
return list;
}
}
bool DefaultOutput::changeOutputDevice( QString id )
{
try
{
IPolicyConfigVista* pPolicyConfig;
ERole reserved = eConsole;
HRESULT hr = CoCreateInstance( __uuidof( CPolicyConfigVistaClient ), NULL, CLSCTX_ALL, __uuidof( IPolicyConfigVista ), (LPVOID*)&pPolicyConfig );
if( SUCCEEDED( hr ) )
{
hr = pPolicyConfig->SetDefaultEndpoint( (PCWSTR)id.toStdU16String().data(), reserved );
pPolicyConfig->Release();
return SUCCEEDED( hr );
}
else
return false;
}
catch( ... )
{
return false;
}
}
QHash<QString, QString> devices = DefaultOutput::enumOutputDevices();
for( QHash<QString, QString>::iterator iter = devices.begin(); iter != devices.end(); iter++ )
{
ui->devicesComboBox->addItem( iter.value(), iter.key() );
}
int index = ui->devicesComboBox->currentIndex();
QString deviceId = ui->devicesComboBox->itemData( index ).toString();
DefaultOutput::changeOutputDevice( deviceId );