Logan
2025-05-26 ab2148ec182db2b5d18d38f2dd690922d2cf56b8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""
  Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
  Reserved. MIT License  (https://opensource.org/licenses/MIT)
  2023 by burkliu(刘柏基) liubaiji@xverse.cn
"""
 
import logging
import argparse
import soundfile as sf
import time
 
import grpc
import paraformer_pb2_grpc
from paraformer_pb2 import Request, WavFormat, DecodeMode
 
 
class GrpcClient:
    def __init__(self, wav_path, uri, mode):
        self.wav, self.sampling_rate = sf.read(wav_path, dtype="int16")
        self.wav_format = WavFormat.pcm
        self.audio_chunk_duration = 1000  # ms
        self.audio_chunk_size = int(self.sampling_rate * self.audio_chunk_duration / 1000)
        self.send_interval = 100  # ms
        self.mode = mode
 
        # connect to grpc server
        channel = grpc.insecure_channel(uri)
        self.stub = paraformer_pb2_grpc.ASRStub(channel)
 
        # start request
        for respond in self.stub.Recognize(self.request_iterator()):
            logging.info(
                "[receive] mode {}, text {}, is final {}".format(
                    DecodeMode.Name(respond.mode), respond.text, respond.is_final
                )
            )
 
    def request_iterator(self, mode=DecodeMode.two_pass):
        is_first_pack = True
        is_final = False
        for start in range(0, len(self.wav), self.audio_chunk_size):
            request = Request()
            audio_chunk = self.wav[start : start + self.audio_chunk_size]
 
            if is_first_pack:
                is_first_pack = False
                request.sampling_rate = self.sampling_rate
                request.mode = self.mode
                request.wav_format = self.wav_format
                if request.mode == DecodeMode.two_pass or request.mode == DecodeMode.online:
                    request.chunk_size.extend([5, 10, 5])
 
            if start + self.audio_chunk_size >= len(self.wav):
                is_final = True
            request.is_final = is_final
            request.audio_data = audio_chunk.tobytes()
            logging.info(
                "[request] audio_data len {}, is final {}".format(
                    len(request.audio_data), request.is_final
                )
            )  # int16 = 2bytes
            time.sleep(self.send_interval / 1000)
            yield request
 
 
if __name__ == "__main__":
    logging.basicConfig(filename="", format="%(asctime)s %(message)s", level=logging.INFO)
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--host", type=str, default="127.0.0.1", required=False, help="grpc server host ip"
    )
    parser.add_argument("--port", type=int, default=10100, required=False, help="grpc server port")
    parser.add_argument("--wav_path", type=str, required=True, help="audio wav path")
    args = parser.parse_args()
 
    for mode in [DecodeMode.offline, DecodeMode.online, DecodeMode.two_pass]:
        mode_name = DecodeMode.Name(mode)
        logging.info("[request] start requesting with mode {}".format(mode_name))
 
        st = time.time()
        uri = "{}:{}".format(args.host, args.port)
        client = GrpcClient(args.wav_path, uri, mode)
        logging.info("mode {}, time pass: {}".format(mode_name, time.time() - st))