【问题标题】:Examining file on different node (different IP address), same network - possible?检查不同节点(不同 IP 地址)、同一网络上的文件 - 可能吗?
【发布时间】:2021-02-19 01:35:52
【问题描述】:

我有一小群 Raspberry Pi,都在同一个本地网络 (192.168.1.2xx) 上都运行 Python 3.7.3,一个 (R Pi CM3) 在 Raspbian Buster 上,另一个 (R Pi 4B 8gig)在 Raspberry Pi OS 64 上。

我在一台设备(Pi 4B)上有一个文件,位于 /tmp/speech.wav,它是实时生成的:

192.168.1.201 - /tmp/speech.wav

我有一个在该设备上运行良好的脚本,它告诉我 .wav 文件的播放持续时间(以秒为单位):

import wave
import contextlib

def getPlayTime():
    fname = '/tmp/speech.wav'
    with contextlib.closing(wave.open(fname,'r')) as f:
        frames = f.getnframes()
        rate = f.getframerate()
        duration = round(frames / float(rate), 2)
        return duration

但是 - 需要对该持续时间信息进行操作的节点正在另一个位于 192.168.1.210 的节点上运行。我不能简单地将各种文件全部移动到同一个节点,因为发生了很多事情,事情在哪里是有原因的。

所以我需要知道的是如何改变我的方法,以便我可以将脚本引用更改为类似以下伪代码的内容:

fname = '/tmp/speech.wav @ 192.168.1.201'

这样的事情可能吗?在网上搜索似乎我遇到了数以百万计的人在寻找如何获取 IP 地址、修复多个 IP 地址问题、修复重复的 IP 地址问题......但我似乎还没有找到如何简单地检查文件正如我在这里描述的那样,在不同的 IP 地址上。我没有网络安全限制,所以任何设置都可以考虑。非常感谢您的帮助。

【问题讨论】:

  • 一种方法是在 PI 上设置一个带有音频文件的 smb 服务器,然后在另一个上使用 smb 客户端安装它以读取文件。您只需将处理实用程序指向挂载点即可通过网络访问文件。
  • 您可能想要配置一个 Samba 服务器并使用 python 模块smbprotocol 访问文件,即:with smbclient.open_file(r"\\server\share\directory\file.txt", mode="w") as fd...
  • 一种方法是在需要共享文件的服务器上运行 opennas,然后在本地使用。

标签: python linux networking raspberry-pi file-properties


【解决方案1】:

有很多可能性,这可能归结为您需要多久检查一次持续时间、多少个客户端、文件更改的频率以及您是否有其他要在节点之间共享的信息。

这里有一些选项:

  • 在具有 WAV 文件的 Pi 上设置 SMB (Samba) 服务器,并让其他节点挂载文件系统并像访问本地文件一样访问文件

  • 在具有 WAV 文件的 Pi 上设置 NFS 服务器,并让其他节点挂载文件系统并像访问本地文件一样访问文件

  • 让其他节点使用ssh 登录并提取持续时间,或使用scp 检索文件 - 请参阅 Python 中的paramiko

  • 在一个节点上设置 Redis 并将 WAV 文件放入其中以便任何人都可以获取它 - 如果您有很多列表、数组、字符串、整数、哈希、队列或您想在 Raspberry Pi 之间快速共享的集合。示例here


这是一个非常简单的示例,它从一个节点(比如 Redis 在 192.168.0.200 上)将音轨写入 Redis 并从任何其他节点读回。当然,您可能只希望写入节点在其中写入持续时间而不是整个轨道 - 这样会更有效率。或者您可能想要存储大量其他共享数据或设置。

这是作者:

#!/usr/bin/env python3

import redis
from pathlib import Path

host='192.168.1.200'

# Connect to Redis
r = redis.Redis(host)

# Load some music, or otherwise create it
music = Path('song.wav').read_bytes()

# Put music into Redis where others can see it
r.set("music",music)

这是读者:

#!/usr/bin/env python3

import redis
from pathlib import Path

host='192.168.1.200'

# Connect to Redis
r = redis.Redis(host)

# Retrieve music track from Redis
music = r.get("music")
print(f'{len(music)} bytes read from Redis')

然后,在测试期间,您可能希望从终端手动将曲目推送到 Redis:

redis-cli -x -h 192.168.0.200 set  music < OtherTrack.wav

或者手动将曲目从 Redis 检索到文件中:

redis-cli -h 192.168.0.200 get music > RetrievedFromRedis.wav

【讨论】:

    【解决方案2】:

    好的,这就是我最终决定的 - 而且效果很好。使用 ZeroMQ 进行消息传递,我具有获取 wav 播放时间的功能,另一个收集有关即将说出的语音的数据,然后在发送语音之前将所有数据发送到电机核心。运动核心处理时间问题以使下巴与语音同步。所以,我实际上并没有将生成 wav 并将 wav 播放时间的长度返回到最终使用它的节点上的代码,但事实证明消息传递足够快,所以有足够的时间空间来接收、处理和执行运动控制以完美匹配语音。在此处发布此内容,以防对以后从事类似问题的人们有所帮助。

    import time
    import zmq
    import os
    import re
    import wave
    import contextlib
    
    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://*:5555")  #Listens for speech to output
    
    print("Connecting to Motor Control")
    jawCmd = context.socket(zmq.PUB)
    jawCmd.connect("tcp://192.168.1.210:5554") #Sends to MotorFunctions for Jaw Movement
    
    def getPlayTime():  # Checks to see if current file duration has changed
        fname = '/tmp/speech.wav'   # and if yes, sends new duration
        with contextlib.closing(wave.open(fname,'r')) as f:
            frames = f.getnframes()
            rate = f.getframerate()
            duration = round(frames / float(rate), 3)
            speakTime = str(duration)
            return speakTime
    
    def set_voice(V,T):
        T2 = '"' + T + '"'
        audioFile = "/tmp/speech.wav"  # /tmp set as tmpfs, or RAMDISK to reduce SD Card write ops
    
        if V == "A":
            voice = "Allison"
        elif V == "B":
            voice = "Belle"
        elif V == "C":
            voice = "Callie"
        elif V == "D":
            voice = "Dallas"
        elif V == "V":
            voice = "David"
        else:
            voice = "Belle"
    
        os.system("swift -n " + voice + " -o " + audioFile + " " +T2) # Record audio
        tailTrim = .5                                                 # Calculate Jaw Timing
        speakTime = eval(getPlayTime())                               # Start by getting playlength
        speakTime = round((speakTime - tailTrim), 2)                  # Chop .5 s for trailing silence
        wordList = T.split()
        jawString = []
        for index in range(len(wordList)):
            wordLen = len(wordList[index])
            jawString.append(wordLen)
        jawString = str(jawString)
        speakTime = str(speakTime)
        jawString = speakTime + "|" + jawString  # 3.456|[4, 2, 7, 4, 2, 9, 3, 4, 3, 6] - will split on "|"
        jawCmd.send_string(jawString)   # Send Jaw Operating Sequence
        os.system("aplay " + audioFile) # Play audio
    
    pronunciationDict = {'teh':'the','process':'prawcess','Maeve':'Mayve','Mariposa':'May-reeposah','Lila':'Lala','Trump':'Ass hole'}
    
    def adjustResponse(response):     # Adjusts spellings in output string to create better speech output.
        for key, value in pronunciationDict.items():
            if key in response or key.lower() in response:
                response = re.sub(key, value, response, flags=re.I)
        return response
    
    SpeakText="Speech center connected and online."
    set_voice(V,SpeakText) # Cepstral  Voices: A = Allison; B = Belle; C = Callie; D = Dallas; V = David;
    
    while True:
        SpeakText = socket.recv().decode('utf-8') # .decode gets rid of the b' in front of the string
        SpeakTextX = adjustResponse(SpeakText)    # Run the string through the pronunciation dictionary
        print("SpeakText = ",SpeakTextX)
    
        set_voice(V,SpeakTextX)
        print("Received request: %s" % SpeakTextX)
        socket.send_string(str(SpeakTextX))       # Send data back to source for confirmation
    

    【讨论】:

      猜你喜欢
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 2013-12-27
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多