Quellcode durchsuchen

Z991239-2175 #comment fix: 本地媒体播放使用免提模式配置的扬声器播放音频

陈礼鹏80274480 vor 4 Jahren
Ursprung
Commit
67ae0838f9

+ 1 - 0
Module/mod_SalesRecorder/mod_SalesRecorder.h

@@ -114,6 +114,7 @@ using namespace SalesRecorder;
 		//virtual void Debug(const char* fmt, ...);
 		virtual void AudioPlayFinished(){}
 		virtual int GetMediaPlayerIcoPath(char* strPath, size_t uLen) {}
+		virtual int GetAudioOutDevName(char* strDev, size_t uLen) {}
 		virtual void Debug(media_loglevel log_level, const char* fmt, ...);
 #endif // RVC_OS_WIN
 

+ 31 - 0
Module/mod_localmediaplay/mod_localmediaplay.cpp

@@ -479,6 +479,19 @@ int CLocalMediaPlayEntity::GetMediaPlayerIcoPath(char* strPath, size_t uLen)
 	return GetPlayerIcoPath(strPath, uLen);
 }
 
+int CLocalMediaPlayEntity::GetAudioOutDevName(char* strDev, size_t uLen)
+{
+	int iRet = -1;
+	int idatalen = m_strAudioOutDev.GetLength();
+	if (uLen > idatalen){
+		memcpy(strDev, m_strAudioOutDev.GetData(), idatalen);
+		iRet = 0;
+		Dbg("%s:%d audio Out Device Name is %s.",__FUNCTION__, __LINE__, strDev);
+	}
+
+	return iRet;
+}
+
 int CLocalMediaPlayEntity::GetPicPlayerIcoPath(char* strPath, size_t uLen)
 {
 	return GetPlayerIcoPath(strPath, uLen);
@@ -520,6 +533,24 @@ int CLocalMediaPlayEntity::GetPlayerIcoPath(char* strPath, size_t uLen)
 
 	return iRet;
 }
+
+
+int CLocalMediaPlayEntity::GetAudioOutDev()
+{
+	int iRet = -1;
+	CSmartPointer<IEntityFunction> spFunction = GetFunction();
+	CSmartPointer<IConfigInfo> spRootConfig;
+	ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spRootConfig);
+	if (Error == Error_Succeed) {
+		SpIniMappingTable table;
+		table.AddEntryString("audio", "handfree_out_dev", m_strAudioOutDev, "$");
+		Error = table.Load(spRootConfig);
+		if (Error == Error_Succeed) {
+			iRet = 0;
+		}
+	}
+	return iRet;
+}
 #endif // RVC_OS_WIN
 
 

+ 6 - 3
Module/mod_localmediaplay/mod_localmediaplay.h

@@ -78,6 +78,7 @@ public:
 	virtual void AudioPlayFinished();
 	virtual int GetMediaPlayerIcoPath(char* strPath, size_t uLen);
 	virtual int GetPicPlayerIcoPath(char* strPath, size_t uLen);
+	virtual int GetAudioOutDevName(char* strDev, size_t uLen);
 	bool GetPlayFlag();
 	bool GetScanExitFlag();
 	
@@ -141,6 +142,9 @@ private:
 	friend void* queryMedia(void* param);
 	friend void* StartAudioPlayingThreadFunc(void* param);
 	friend void* StartMediaPlayFunc(void* param);
+
+	int GetPlayerIcoPath(char* strPath, size_t uLen);
+	int GetAudioOutDev();
 #endif // RVC_OS_WIN
 
 	void setMediaPath();
@@ -148,8 +152,6 @@ private:
 	bool SecureClientConnect();
 
 	void loadDefaultMedia();
-
-	int GetPlayerIcoPath(char* strPath, size_t uLen);
 private:
 	int m_id_seq;
 	CUUID m_SubIDIEIdle;
@@ -172,7 +174,7 @@ private:
 	MediaPlayParam m_mediaParam;
 	int m_defaultVolum;
 	std::string m_lastPlayAudio;
-
+	
 #ifdef RVC_OS_WIN
 	HANDLE m_scanThread, m_playThread;
 	vector<CWmpPlayConfig> m_defaultVideo;
@@ -186,6 +188,7 @@ private:
 	pthread_t m_uMediaPlayThreadId;
 	bool m_badplayflag;
 	bool m_scanexitflag;
+	CSimpleStringA m_strAudioOutDev;
 #endif // RVC_OS_WIN
 };
 

+ 26 - 23
Other/libmediaplayer/audio.cpp

@@ -372,29 +372,31 @@ static int open_audio_playing(void *arg)
     wanted_spec.userdata = is;                          // 提供给回调函数的参数
 	
 	int iaudioapeaker = SDL_GetNumAudioDevices(0);
+	const char* strdevname = NULL;
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio output device number is %d.", iaudioapeaker);
 	for (int i = 0; i < iaudioapeaker; i++) {
 		is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "device id %d audio device name is %s.", i, SDL_GetAudioDeviceName(i, 0));
+		if (is->paudiodev && strstr(SDL_GetAudioDeviceName(i, 0), is->paudiodev)){
+			strdevname = SDL_GetAudioDeviceName(i, 0);
+			is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "mathed audio device name is %s.", strdevname);
+		}
 	}
+	is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "current audio driver name is %s.", SDL_GetCurrentAudioDriver());
+	//{
+	//	int inum = SDL_GetNumAudioDrivers();
+	//	int i = 0;
+	//	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "Audio Drivers number is %d.", inum);
+	//	for (; i < inum; i++) {
+	//		const char* drivername = SDL_GetAudioDriver(i);
+	//		is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "[%d] Audio Drivers name is %s.", i, drivername);
+	//	}
+	//}
 
-	if (SDL_OpenAudio(&wanted_spec, &actual_spec) < 0){
-		is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_OpenAudio() failed: %s.", SDL_GetError());
-		return -1;
-    }
-	else {
-		is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "-----------SDL_OpenAudio() success:");
+	//SDL_AudioDeviceID audio_dev = 0;
+	while (!(audio_dev = SDL_OpenAudioDevice(strdevname, 0, &wanted_spec, &actual_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))){
+		is->rvc_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_OpenAudio (%d channels, %d Hz): %s",wanted_spec.channels, wanted_spec.freq, SDL_GetError());
 	}
 
-	//SDL_AudioDeviceID idev = 0;
-	//idev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &actual_spec, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
-	//if (0 == idev) {
-	//	is->rvc_hostapi->Debug("SDL Open Audio Device failed: %s.", SDL_GetError());
-	//	return -1;
-	//}
-	//else {
-	//	is->rvc_hostapi->Debug("-----------SDL Open Audio Device{id=%d} success.", idev);
-	//}
-
     // 2.2 根据SDL音频参数构建音频重采样参数
     // wanted_spec是期望的参数,actual_spec是实际的参数,wanted_spec和auctual_spec都是SDL中的参数。
     // 此处audio_param是FFmpeg中的参数,此参数应保证是SDL播放支持的参数,后面重采样要用到此参数
@@ -409,8 +411,8 @@ static int open_audio_playing(void *arg)
     is->audio_param_tgt.bytes_per_sec = av_samples_get_buffer_size(NULL, actual_spec.channels, actual_spec.freq, is->audio_param_tgt.fmt, 1);
     if (is->audio_param_tgt.bytes_per_sec <= 0 || is->audio_param_tgt.frame_size <= 0){
 		is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "av_samples_get_buffer_size failed.");
-		//SDL_CloseAudioDevice(idev);
-		SDL_CloseAudio();
+		SDL_CloseAudioDevice(audio_dev);
+		//SDL_CloseAudio();
 		return -1;
     }
     is->audio_param_src = is->audio_param_tgt;
@@ -422,15 +424,15 @@ static int open_audio_playing(void *arg)
     //     打开音频设备后默认未启动回调处理,通过调用SDL_PauseAudio(0)来启动回调处理。
     //     这样就可以在打开音频设备后先为回调函数安全初始化数据,一切就绪后再启动音频回调。
     //     在暂停期间,会将静音值往音频设备写。
-    SDL_PauseAudio(0);
-	//SDL_PauseAudioDevice(idev, 0);
+    //SDL_PauseAudio(0);
+	SDL_PauseAudioDevice(audio_dev, 0);
 
 	while (is->abort_request == 0){
 		SDL_Delay(1);
 	}
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "----------%s:%d before SDL Close Audio", __FUNCTION__, __LINE__);
-	SDL_CloseAudio();
-	//SDL_CloseAudioDevice(idev);
+	//SDL_CloseAudio();
+	SDL_CloseAudioDevice(audio_dev);
 	is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "---------%s:%d after SDL Close Audio", __FUNCTION__, __LINE__);
 
 	return 0;
@@ -487,7 +489,8 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
 				//is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "on_audio_volume success.");
 			}
 			//is->rvc_hostapi->Debug(MEDIA_LOG_DEBUG, "audio uVolume is %d.", ivolume);
-			SDL_MixAudio(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, len1, ivolume);
+			//SDL_MixAudio(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, len1, ivolume);
+			SDL_MixAudioFormat(stream, (uint8_t*)is->p_audio_frm + is->audio_cp_index, AUDIO_S16SYS, len1, ivolume);
         }
         else{
 			SDL_memset(stream, 0, len1);

+ 1 - 0
Other/libmediaplayer/idatastruct.h

@@ -72,4 +72,5 @@ struct RVC_NO_VTABLE CMediaHostApi
 	virtual void Debug(media_loglevel log_level, const char* fmt, ...) = 0;
 	virtual void AudioPlayFinished() = 0;
 	virtual int GetMediaPlayerIcoPath(char* strPath, size_t uLen) = 0;
+	virtual int GetAudioOutDevName(char* strDev, size_t uLen) = 0;
 };

+ 19 - 2
Other/libmediaplayer/player.cpp

@@ -169,12 +169,18 @@ CMediaPlayer::CMediaPlayer(CMediaHostApi* pHostApi)
 	m_uvolume = SDL_MIX_MAXVOLUME/2;
 	m_bplaying = false;
 	m_piconpath = NULL;
+	m_paudiodev = NULL;
 	
 	if (NULL != m_hostapi){
 		char str_iconpath[MAX_PATH] = {0};
 		if (0 == pHostApi->GetMediaPlayerIcoPath(str_iconpath, MAX_PATH)){
 			m_piconpath = av_strdup(str_iconpath);
 		}
+
+		char str_audiodev[MAX_PATH] = { 0 };
+		if (0 == pHostApi->GetAudioOutDevName(str_audiodev, MAX_PATH)) {
+			m_paudiodev = av_strdup(str_audiodev);
+		}
 	}
 	else {
 		m_hostapi->Debug(MEDIA_LOG_DEBUG, "new CMediaPlayer failed!");
@@ -204,6 +210,12 @@ CMediaPlayer::~CMediaPlayer()
 
 	if (NULL != m_piconpath) {
 		av_free(m_piconpath);
+		m_piconpath = NULL;
+	}
+
+	if (NULL != m_paudiodev){
+		av_free(m_paudiodev);
+		m_paudiodev = NULL;
 	}
 
 	Uint32 uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
@@ -274,6 +286,10 @@ int CMediaPlayer::Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player
 	if (NULL != m_piconpath){
 		m_player_stat->piconpath = av_strdup(m_piconpath);
 	}
+
+	if (NULL != m_paudiodev){
+		m_player_stat->paudiodev = av_strdup(m_paudiodev);
+	}
 	m_player_stat->uVolume = m_uvolume;
 	m_player_stat->uFilesCount = pMedia_Player->uFilesCount;
 	for (size_t i = 0; i < pMedia_Player->uFilesCount; i++){
@@ -448,8 +464,9 @@ int CMediaPlayer::StopMediaPlay()
 	m_hostapi->Debug(MEDIA_LOG_DEBUG, "set m_player_stat abort_request flag to true.");
 	m_player_stat->abort_request = 1;
 	if (m_bplaying) {
-		m_hostapi->Debug(MEDIA_LOG_DEBUG, "user stop audio play set SDL_PauseAudio param to 1.");
-		SDL_PauseAudio(1);
+		m_hostapi->Debug(MEDIA_LOG_DEBUG, "user stop audio play set SDL_PauseAudioDevice param to 1.");
+		//SDL_PauseAudio(1);
+		SDL_PauseAudioDevice(audio_dev, 1);
 	}
 
 	iRet = 0;

+ 3 - 0
Other/libmediaplayer/player.h

@@ -206,6 +206,7 @@ typedef struct player_stat_s{
 	
 	play_media_callback_t* prvc_cb;	// 播放状态回调函数
 	char* piconpath;				// icon图标路径
+	char* paudiodev;				// 音频输出设备名
 	eMediaType_t eMType;			// 媒体类型
 	eWindType_t eWindType;			// 视频框大小类型
 	volatile uint8_t uVolume;		// 音量大小1-128
@@ -245,6 +246,7 @@ double get_clock(play_clock_t *c);
 void set_clock_at(play_clock_t *c, double pts, int serial, double time);
 void set_clock(play_clock_t *c, double pts, int serial);
 
+static SDL_AudioDeviceID audio_dev;
 
 class CMediaPlayer
 {
@@ -270,5 +272,6 @@ private:
 	uint8_t m_uvolume;
 	CMediaHostApi* m_hostapi;
 	char* m_piconpath;				// ico图标路径
+	char* m_paudiodev;				// 音频输出设备
 };