Nao 是一个可爱活泼的机器人,可以在它身上进行很多有趣的开发,当 Nao 可以获取到环境的语音信息之后又可以做什么有趣的事情呢?
这个问题留给读者自己探索,下面我们介绍一下如何使得 Nao 通过录音的方式,获取到环境的语音信息。
在开发的时候,通过 Naoqi API 进行对 Nao 的服务控制,要求本地的开发环境安装有 python 2.7,python 版本的 naoqi-sdk。当然,开发环境视情况而定,也可以是 C++、Java。
在本地上,主要是通过 Proxy 代理的模式,调用 ALAudioRecorder API
控制 Nao 的四个麦克风进行录音。
一、录音
1.1 只需要知道当前 Nao 的 IP 地址,即可通过 ALProxy 找到她的 API 接口。
from naoqi import ALProxy
class NaoRecode:
def __init__(self, ip='192.168.124.2', port=9559):
self.ip = ip
self.port = port
self.audio_recorder = None
self.__connection_nao()
def __connection_nao(self):
try:
self.audio_recorder = ALProxy('ALAudioRecorder', self.ip, self.port)
except RuntimeError as e:
print 'proxy-连接nao失败'
else:
print 'proxy-连接nao成功'
if __name__ == '__main__':
nao_recode = NaoRecode(ip='192.168.124.2')
2.1 连接成功后,便可以对 Nao 进行录音。因为 Nao 有四个麦克风,所以需要一个栈[0, 1]
状态来控制使用哪一个麦克风。避免文件累积过多,造成使用空间的浪费,创建临时文件来存放录音数据。
import time
import tempfile
class NaoRecode:
def __init__(self, ip='192.168.124.2', port=9559):
self.ip = ip
self.port = port
self.audio_recorder = None
self.__connection_nao()
# 录音:4声道,16000采样率
def recode(self):
x = list()
x.append(1) # Left 左麦克风
x.append(1) # Right 右麦克风
x.append(1) # Front 前麦克风
x.append(1) # Rear 后麦克风
y = tuple(x)
tf = tempfile.NamedTemporaryFile() # 创建临时存储文件
fp = tf.name
print '开始录音'
try:
self.audio_recorder.stopMicrophonesRecording()
self.audio_recorder.startMicrophonesRecording(fp, "wav", 16000, y)
time.sleep(5) # 录音 5 秒
self.audio_recorder.stopMicrophonesRecording()
except RuntimeError as e:
print '录音失败'
tf.close() # 关闭临时文件-->清除临时文件
else:
print '录音成功'
print 'Nao 上录音文件路径' + fp
tf.close() # 关闭临时文件-->清除临时文件
return fp # 返回录音文件的地址
if __name__ == '__main__':
nao_recode = NaoRecode(ip='192.168.124.2')
file_path_local = nao_recode.recode()
这样就已经完成了 Nao 录音的工作,但是录音文件是存放在 Nao 身上的,在本地开发的需要,所以我们还需要把录音文件通过 ftp 协议下载到本地。
二、下载录音文件
2.1 使用 ftp 协议得先知道服务器的 IP 地址,登录用户的账号、密码,需要下载的文件路径地址,以及本地存放的路径地址。
import paramiko
import os
class DownloadFile:
def __init__(self, hostname=None, port=22, username=None, password=None):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.client = None
self.__connection_with_ftp()
def __connection_with_ftp(self):
client = paramiko.Transport(self.hostname, self.port)
try:
client.connect(username=self.username, password=self.password) # 连接服务器
except:
print 'ftp-连接nao失败'
else:
print 'ftp-连接nao成功'
self.client = client
def download_file(self, file_remote, file_local):
file_remote = file_remote
file_local = file_local
try:
sftp = paramiko.SFTPClient.from_transport(self.client)
sftp.get(remotepath=file_remote, localpath=file_local)
except:
print '文件 ' + file_remote + ' 下载失败'
os.remove(file_local)
else:
print '文件 ' + file_remote + ' 下载成功'
if __name__ == '__main__':
file_dir = '/home/yld/test.txt'
file_loc = '../audio_file/test.txt'
download_audio = DownloadFile(hostname='192.168.124.2', username='nao', password='nao')
download_audio.download_file(file_remote=file_dir, file_local=file_loc)
2.2 这时候只需要调用 DownloadFile.download()
方法即可吧 Nao 上的录音文件下载到本地。
from download_file import DownloadFile
import time
class NaoRecode:
def __init__(self, ip='192.168.124.2', port=9559):
self.ip = ip
self.port = port
self.audio_recorder = None
self.__connection_nao()
# 录音:4声道,16000采样率
def recode(self):
x = list()
x.append(1) # Left 左麦克风
x.append(1) # Right 右麦克风
x.append(1) # Front 前麦克风
x.append(1) # Rear 后麦克风
y = tuple(x)
tf = tempfile.NamedTemporaryFile() # 创建临时存储文件
fp = tf.name
print '开始录音'
try:
self.audio_recorder.stopMicrophonesRecording()
self.audio_recorder.startMicrophonesRecording(fp, "wav", 16000, y)
time.sleep(5) # 录音 5 秒
self.audio_recorder.stopMicrophonesRecording()
except RuntimeError as e:
print '录音失败'
tf.close() # 关闭临时文件-->清除临时文件
else:
print '录音成功'
print 'Nao 上录音文件路径' + fp
real_time = time.time() # 获取当前系统时间-->毫秒级
file_name = 'recode-' + str(real_time) + '.wav'
fp = self.__download_audio_file(file_remote=fp, file_name=file_name)
tf.close() # 关闭临时文件-->清除临时文件
return fp # 返回录音文件的地址
# 把录音文件下载到本地
def __download_audio_file(self, file_remote, file_name):
file_remote = file_remote
file_local = './audio_file/' + file_name
try:
download_audio = DownloadFile(hostname=self.ip, port=22, username='nao', password='nao')
download_audio.download_file(file_remote=file_remote, file_local=file_local)
except:
print '录音文件下载失败 ' + file_remote
return file_local
if __name__ == '__main__':
nao_recode = NaoRecode(ip='192.168.124.2')
file_path_local = nao_recode.recode()
print '本地路径' + file_path_local
三、完整代码
3.1 nao_recode.py
from naoqi import ALProxy
from download_file import DownloadFile
import time
import tempfile
class NaoRecode:
def __init__(self, ip='192.168.124.2', port=9559):
self.ip = ip
self.port = port
self.audio_recorder = None
self.__connection_nao()
def __connection_nao(self):
try:
self.audio_recorder = ALProxy('ALAudioRecorder', self.ip, self.port)
except RuntimeError as e:
print 'proxy-连接nao失败'
else:
print 'proxy-连接nao成功'
# 录音:4声道,16000采样率
def recode(self):
x = list()
x.append(1) # Left 左麦克风
x.append(1) # Right 右麦克风
x.append(1) # Front 前麦克风
x.append(1) # Rear 后麦克风
y = tuple(x)
tf = tempfile.NamedTemporaryFile() # 创建临时存储文件
fp = tf.name
print '开始录音'
try:
self.audio_recorder.stopMicrophonesRecording()
self.audio_recorder.startMicrophonesRecording(fp, "wav", 16000, y)
time.sleep(5) # 录音 5 秒
self.audio_recorder.stopMicrophonesRecording()
except RuntimeError as e:
print '录音失败'
tf.close() # 关闭临时文件-->清除临时文件
else:
print '录音成功'
print 'Nao 上录音文件路径' + fp
real_time = time.time() # 获取当前系统时间-->毫秒级
file_name = 'recode-' + str(real_time) + '.wav'
fp = self.__download_audio_file(file_remote=fp, file_name=file_name)
tf.close() # 关闭临时文件-->清除临时文件
return fp # 返回录音文件的地址
# 把录音文件下载到本地
def __download_audio_file(self, file_remote, file_name):
file_remote = file_remote
file_local = './audio_file/' + file_name
try:
download_audio = DownloadFile(hostname=self.ip, port=22, username='nao', password='nao')
download_audio.download_file(file_remote=file_remote, file_local=file_local)
except:
print '录音文件下载失败 ' + file_remote
return file_local
if __name__ == '__main__':
nao_recode = NaoRecode(ip='192.168.124.2')
file_path_local = nao_recode.recode()
print '本地路径' + file_path_local
3.2 download_file.py
import paramiko
import os
class DownloadFile:
def __init__(self, hostname=None, port=22, username=None, password=None):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.client = None
self.__connection_with_ftp()
def __connection_with_ftp(self):
client = paramiko.Transport(self.hostname, self.port)
try:
client.connect(username=self.username, password=self.password) # 连接服务器
except:
print 'ftp-连接nao失败'
else:
print 'ftp-连接nao成功'
self.client = client
def download_file(self, file_remote, file_local):
file_remote = file_remote
file_local = file_local
try:
sftp = paramiko.SFTPClient.from_transport(self.client)
sftp.get(remotepath=file_remote, localpath=file_local)
except:
print '文件 ' + file_remote + ' 下载失败'
os.remove(file_local)
else:
print '文件 ' + file_remote + ' 下载成功'
if __name__ == '__main__':
file_dir = '/home/yld/test.txt'
file_loc = '../audio_file/test.txt'
download_audio = DownloadFile(hostname='192.168.121.2', username='nao', password='nao')
download_audio.download_file(file_remote=file_dir, file_local=file_loc)