实战 Zabbix 与 Jenkins 语音合成与播报功能

1.准备

1):讯飞开发者账号。

2):讯飞语音合成Linux sdk,会一点C语言或者找会C的开发,目前不能超过2048超过需要增加逻辑并做容错机制。
实战 Zabbix 与 Jenkins 语音合成与播报功能_第1张图片实战 Zabbix 与 Jenkins 语音合成与播报功能_第2张图片实战 Zabbix 与 Jenkins 语音合成与播报功能_第3张图片
在这里插入图片描述
3):Zabbix 整理告警等级,并定时将Disaster级别的告警信息输出到指定文件。
采集zabbix Disaster级别告警信息 :https://blog.csdn.net/meijinmeng/article/details/103320696

4):Jenkins整理输出信息到指定文件。

2.云上合成语音

1):sdk 语音合成基础代码部分

注意:SDK中-->samples/tts_sample/tts_sample.c 
		                samples/tts_sample/64bit_make.sh

/*

* 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的

* 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的

* 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。

*/



#include 

#include 

#include 

#include 



#include "qtts.h"

#include "msp_cmn.h"

#include "msp_errors.h"



/* wav音频头部格式 */

typedef struct _wave_pcm_hdr

{

	char            riff[4];                // = "RIFF"

	int		size_8;                 // = FileSize - 8

	char            wave[4];                // = "WAVE"

	char            fmt[4];                 // = "fmt "

	int		fmt_size;		// = 下一个结构体的大小 : 16



	short int       format_tag;             // = PCM : 1

	short int       channels;               // = 通道数 : 1

	int		samples_per_sec;        // = 采样率 : 8000 | 6000 | 11025 | 16000

	int		avg_bytes_per_sec;      // = 每秒字节数 : samples_per_sec * bits_per_sample / 8

	short int       block_align;            // = 每采样点字节数 : wBitsPerSample / 8

	short int       bits_per_sample;        // = 量化比特数: 8 | 16



	char            data[4];                // = "data";

	int		data_size;              // = 纯数据长度 : FileSize - 44 

} wave_pcm_hdr;



/* 默认wav音频头部数据 */

wave_pcm_hdr default_wav_hdr = 

{

	{ 'R', 'I', 'F', 'F' },

	0,

	{'W', 'A', 'V', 'E'},

	{'f', 'm', 't', ' '},

	16,

	1,

	1,

	16000,

	32000,

	2,

	16,

	{'d', 'a', 't', 'a'},

	0  

};

/* 文本合成 */

int text_to_speech(const char* filename, const char* des_path, const char* params)

{

	int          ret          = -1;

	FILE*        fp           = NULL;

	FILE*        in           = NULL;
	
	const char*  sessionID    = NULL;

	unsigned int audio_len    = 0;

	wave_pcm_hdr wav_hdr      = default_wav_hdr;

	int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;

	int file_length = 0;
	char *src_text = NULL;
	
	if (NULL == filename || NULL == des_path)

	{

		printf("params is error!\n");

		return ret;

	}

	in = fopen(filename, "rb");
	if(NULL == in) {
		printf("open %s error.\n", filename);
		return ret;
	}
	
	fp = fopen(des_path, "wb");

	if (NULL == fp)

	{

		printf("open %s error.\n", des_path);

		return ret;

	}

	fseek(in, 0L, SEEK_END);
	file_length = ftell(in);
	src_text = (char *)malloc(file_length+1);
	if(NULL == src_text) {
		printf("askMemFailed.\n");
		fclose(in);
		fclose(fp);
		return ret;
	}
	
	fseek(in, 0L, SEEK_SET);
	fread(src_text,file_length,1,in);
	src_text[file_length] = '\0';

	/* 开始合成 */

	sessionID = QTTSSessionBegin(params, &ret);

	if (MSP_SUCCESS != ret)

	{

		printf("QTTSSessionBegin failed, error code: %d.\n", ret);

		fclose(fp);
		fclose(in);
		free(src_text);
		return ret;

	}

	ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);

	if (MSP_SUCCESS != ret)

	{

		printf("QTTSTextPut failed, error code: %d.\n",ret);

		QTTSSessionEnd(sessionID, "TextPutError");

		fclose(fp);
		fclose(in);
		free(src_text);
		return ret;

	}

	printf("正在合成 ...\n");

	fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000

	while (1) 

	{

		/* 获取合成音频 */

		const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);

		if (MSP_SUCCESS != ret)

			break;

		if (NULL != data)

		{

			fwrite(data, audio_len, 1, fp);

		    wav_hdr.data_size += audio_len; //计算data_size大小

		}

		if (MSP_TTS_FLAG_DATA_END == synth_status)

			break;

		printf(">");

		usleep(150*1000); //防止频繁占用CPU

	}

	printf("\n");

	if (MSP_SUCCESS != ret)

	{

		printf("QTTSAudioGet failed, error code: %d.\n",ret);

		QTTSSessionEnd(sessionID, "AudioGetError");

		fclose(fp);
		fclose(in);
		free(src_text);
		return ret;

	}

	/* 修正wav文件头数据的大小 */

	wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8);

	

	/* 将修正过的数据写回文件头部,音频文件为wav格式 */

	fseek(fp, 4, 0);

	fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值

	fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置

	fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值

	fclose(fp);
	fclose(in);
	if(src_text)
		free(src_text);
	src_text = NULL;
	fp = NULL;

	/* 合成完毕 */

	ret = QTTSSessionEnd(sessionID, "Normal");

	if (MSP_SUCCESS != ret)

	{

		printf("QTTSSessionEnd failed, error code: %d.\n",ret);

	}



	return ret;

}



int main(int argc, char* argv[])

{

	int         ret                  = MSP_SUCCESS;

	const char* login_params         = "appid = 59a4c2a0, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动

	/*

	* rdn:           合成音频数字发音方式

	* volume:        合成音频的音量

	* pitch:         合成音频的音调

	* speed:         合成音频对应的语速

	* voice_name:    合成发音人

	* sample_rate:   合成音频采样率

	* text_encoding: 合成文本编码格式

	*

	*/

	const char* session_begin_params = "voice_name = xiaoyan, text_encoding = utf8, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";

	const char* filename             = "tts_sample.wav"; //合成的语音文件名称

	const char* text                 = "/tmp/error.log"; //合成文本



	/* 用户登录 */

	ret = MSPLogin(NULL, NULL, login_params);//第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取

	if (MSP_SUCCESS != ret)

	{

		printf("MSPLogin failed, error code: %d.\n", ret);

		goto exit ;//登录失败,退出登录

	}

	printf("\n###########################################################################\n");

	printf("## 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的 ##\n");

	printf("## 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的  ##\n");

	printf("## 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。  ##\n");

	printf("###########################################################################\n\n");

	/* 文本合成 */

	printf("开始合成 ...\n");

	ret = text_to_speech(text, filename, session_begin_params);

	if (MSP_SUCCESS != ret)

	{

		printf("text_to_speech failed, error code: %d.\n", ret);

	}

	printf("合成完毕\n");



exit:

	/*printf("按任意键退出 ...\n");*/

	/*getchar();*/

	MSPLogout(); //退出登录



	return 0;

}

`



2):Zabbix合成部分
	
	```bash
	#!/bin/bash
	
	#1.清空上次记录
	#>/tmp/error.log
	
	
	
	#2.获取程序报错数量
	#projects='orders platform goods webmanager distribution gateway payment account physique marketing device-distribution wechatmanager eureka ifly-skill gen2-core gen2-cmos gen1-core gen1-cmos recommend wechatseller tag'
	
	#for i in $projects  
	#  do
	#   echo "$i 的报错数量:">>/tmp/error.log
	#   zabbix_get -s 127.0.0.1 -p 10050 -k "error_count[$i]">>/tmp/error.log
	#done
	
	
	#3.获取zabbix api最新的严重告警信息
	alert=""
	python /srv/zabbix_py.py>/tmp/zabbix.log
	alert=`cat /tmp/zabbix.log`
	
	
	if [ ${#alert} -eq 0 ];then
		echo "zabbix暂无严重告警,感谢收听再见">>/tmp/alert.log
		#rm -f /application/demon/bin/tts_sample.wav
	        #jenkins 发包播报
	        #echo "$jenkins">>/tmp/error.log
	        #4.合成语音部门
	        #cd /application/demon/samples/tts_sample
	        #source  64bit_make.sh
	        #cd /application/demon/bin
	        #./tts_sample
	
	else
		echo "$alert">>/tmp/error.log
		#4.合成语音部门
		cd /application/demon/samples/tts_sample
		source  64bit_make.sh
		cd /application/demon/bin
		./tts_sample
	
	
	fi
	
		
	```


**3):Jenkins 合成部分** 

			```bash
			#!/bin/bash
			
			#1.清空上次记录
			#>/tmp/error.log
			chmod 777 /tmp/jenkins.log
			chmod 777 /tmp/error.log
			chmod 777 /tmp/zabbix.log
			chmod 777 /tmp/alert.log
			
			#2.获取程序报错数量
			#projects='orders platform goods webmanager distribution gateway payment account physique marketing device-distribution wechatmanager eureka ifly-skill gen2-core gen2-cmos gen1-core gen1-cmos recommend wechatseller tag'
			
			#for i in $projects  
			#  do
			#   echo "$i 的报错数量:">>/tmp/error.log
			#   zabbix_get -s 127.0.0.1 -p 10050 -k "error_count[$i]">>/tmp/error.log
			#done
			
			
			#3.获取zabbix api最新的严重告警信息
			alert=""
			python /srv/zabbix_py.py>/tmp/zabbix.log
			
			if [ ! -f "/tmp/jenkins.log" ]; then
				touch /tmp/jenkins.log
			else
			  alert=`cat /tmp/zabbix.log`
			  jenkins=`cat /tmp/jenkins.log`
			
			  if [ ${#alert} -eq 0 ];then
			        echo "$(date +%F-%H:%M:%S) zabbix暂无严重告警,感谢收听再见">>/tmp/alert.log
			        #rm -f /application/demon/bin/tts_sample.wav
			        if [ ${#jenkins} -eq 0 ];then
			                echo "jenkins 无发包任务,感谢收听再见">>/tmp/alert.log
			                #rm -f /application/demon/bin/tts_sample.wav
			        else
			                #jenkins 发包播报
			                echo "$jenkins">/tmp/error.log
			                #4.合成语音部门
			                cd /application/demon/samples/tts_sample
			                source  64bit_make.sh
			                cd /application/demon/bin
			                ./tts_sample
					cp /application/demon/bin/tts_sample.wav  /home/user && chown user.user /home/user/tts_sample.wav
					rm -f /application/demon/bin/tts_sample.wav
			        fi
			
			
			  fi
			
			
			fi
			
			```

3.语音传输并播报

1):windows

#bat脚本

@echo off
  if "%1" == "h" goto begin
  mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
	taskkill /f /t /im wmplayer.exe
	del  /f /s /q "C:\Download\tts_sample.wav"

	
	"C:\Program Files\WinSCP\WinSCP" /console /command "option batch continue"  "option confirm off" "open sftp://root:[email protected]:22" "option transfer binary" "get /application/demon/bin/tts_sample.wav C:\Download\" "exit" /log=C:\Download\log_file.txt 

	
	SET Source="C:\Download\tts_sample.wav" 
	if exist %Source% (
		start "%ProgramFiles(x86)%\Windows  Media Player\wmplayer.exe" "C:\Download\tts_sample.wav" -min
		"D:\application\PotPlayer\PotPlayerMini64.exe" "D:\tts_sample.wav" -autoexit
		"C:\Program Files\WinSCP\WinSCP.com" /command "open sftp://root:[email protected]:22  -explicit" "rm /application/demon/bin/tts_sample.wav" "exit"
		"C:\Program Files\WinSCP\WinSCP.com" /command "open sftp://root:[email protected]:22  -explicit" "rm /tmp/error.log" "exit"
		"C:\Program Files\WinSCP\WinSCP.com" /command "open sftp://root:[email protected]:22  -explicit" "rm /tmp/jenkins.log" "exit"
		
		::"D:\application\PotPlayer\PotPlayerMini64.exe" "D:\tts_sample.wav" -autoexit
		exit 
	) else (
		taskkill /f /t /im wmplayer.exe
		taskkill /f /t /im "PotPlayerMini64.exe"
		exit 
	)
2):Linux(ubuntu)
	

	```bash
	#!/bin/bash
	
	#1.删除本地播放任务和视频文件
	rm -f /application/tts_sample.wav
	
	
	#2.下载远程音频文件
	scp -P 1622 [email protected]:/home/user/tts_sample.wav   /application/tts_sample.wav
	
	
	#3.后台播放音频文件
	if [ ! -f "/application/tts_sample.wav" ];then 
		exit 
	else
		#播放音频
		cd /application
		aplay tts_sample.wav & 
		if [ $? -eq 0 ];then		
			#4.播放完成后删除远程音频文件和error.log  jenkins.log
			ssh -p 1622 [email protected] "cd /home/user && rm -f tts_sample.wav"
			ssh -p 1622 [email protected] "> /tmp/error.log &&  >/tmp/jenkins.log"
			echo "aplay 播放成功">>/application/aplay.log
	
		else
	
			echo "aplay 播放失败">>/application/aplay.log
		fi	
	fi
	
	```

4.总结

	以上设置好后,使用4个月成功率高达98%以上,基本实现了播报需求。
	1.核心sdk c语言脚本的合成部分。
	2.zabbix 和 jenkins播报不能有冲突,需要有一个优先级。
	3.语音播放后不能有重复或者漏播情况,需要播放后删除源音频文件。
	4.播放语音的机器需要长期稳定,最好是Ubuntu系统。

你可能感兴趣的:(监控系统及应用)