or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-clients.mdconfiguration-types.mdindex.mdlong-audio-synthesis.mdspeech-synthesis.mdstreaming-synthesis.mdvoice-management.md

streaming-synthesis.mddocs/

0

# Streaming Synthesis

1

2

## Overview

3

4

Streaming synthesis enables real-time, bidirectional audio generation where text can be sent incrementally and audio is received as it's generated. This is ideal for interactive applications like chatbots, live assistants, and real-time communication systems where low latency is crucial.

5

6

## Core Streaming Operations

7

8

### Basic Streaming Setup

9

10

```api { .api }

11

from google.cloud import texttospeech

12

13

# Initialize client for streaming

14

client = texttospeech.TextToSpeechClient()

15

16

# Configure streaming synthesis

17

config = texttospeech.StreamingSynthesizeConfig(

18

voice=texttospeech.VoiceSelectionParams(

19

language_code="en-US",

20

name="en-US-Neural2-A"

21

),

22

audio_config=texttospeech.StreamingAudioConfig(

23

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

24

sample_rate_hertz=22050

25

)

26

)

27

28

# Create streaming request iterator

29

def create_streaming_requests():

30

# First request with configuration

31

yield texttospeech.StreamingSynthesizeRequest(streaming_config=config)

32

33

# Input requests

34

yield texttospeech.StreamingSynthesizeRequest(

35

input=texttospeech.StreamingSynthesisInput(text="Hello, ")

36

)

37

yield texttospeech.StreamingSynthesizeRequest(

38

input=texttospeech.StreamingSynthesisInput(text="this is streaming synthesis.")

39

)

40

41

# Perform streaming synthesis

42

streaming_responses = client.streaming_synthesize(create_streaming_requests())

43

44

# Process responses

45

for response in streaming_responses:

46

if response.audio_content:

47

# Handle audio chunks as they arrive

48

print(f"Received audio chunk: {len(response.audio_content)} bytes")

49

# Process or play audio chunk immediately

50

```

51

52

### Streaming with SSML

53

54

```api { .api }

55

from google.cloud.texttospeech import (

56

StreamingSynthesizeRequest,

57

StreamingSynthesizeConfig,

58

StreamingSynthesisInput,

59

StreamingAudioConfig

60

)

61

62

def streaming_ssml_synthesis():

63

"""Stream SSML content with markup."""

64

client = texttospeech.TextToSpeechClient()

65

66

# Configure for SSML streaming

67

config = StreamingSynthesizeConfig(

68

voice=texttospeech.VoiceSelectionParams(

69

language_code="en-US",

70

name="en-US-Wavenet-D"

71

),

72

audio_config=StreamingAudioConfig(

73

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

74

sample_rate_hertz=24000

75

)

76

)

77

78

def request_generator():

79

# Configuration request

80

yield StreamingSynthesizeRequest(streaming_config=config)

81

82

# SSML input chunks

83

ssml_parts = [

84

'<speak><prosody rate="slow">Hello there!</prosody>',

85

'<break time="1s"/>',

86

'<prosody pitch="+5st">This is exciting!</prosody>',

87

'</speak>'

88

]

89

90

for ssml_part in ssml_parts:

91

yield StreamingSynthesizeRequest(

92

input=StreamingSynthesisInput(markup=ssml_part)

93

)

94

95

# Stream and collect audio

96

responses = client.streaming_synthesize(request_generator())

97

98

audio_chunks = []

99

for response in responses:

100

if response.audio_content:

101

audio_chunks.append(response.audio_content)

102

103

return b''.join(audio_chunks)

104

105

# Usage

106

streaming_audio = streaming_ssml_synthesis()

107

```

108

109

## Configuration Classes

110

111

### StreamingSynthesizeConfig

112

113

```api { .api }

114

from google.cloud.texttospeech import (

115

StreamingSynthesizeConfig,

116

VoiceSelectionParams,

117

StreamingAudioConfig,

118

AudioEncoding

119

)

120

121

# Complete streaming configuration

122

streaming_config = StreamingSynthesizeConfig(

123

voice=VoiceSelectionParams(

124

language_code="en-US",

125

name="en-US-Neural2-C",

126

ssml_gender=texttospeech.SsmlVoiceGender.FEMALE

127

),

128

audio_config=StreamingAudioConfig(

129

audio_encoding=AudioEncoding.LINEAR16,

130

sample_rate_hertz=22050,

131

speaking_rate=1.1, # Optional: speech rate

132

pitch=2.0, # Optional: pitch adjustment

133

volume_gain_db=1.5 # Optional: volume gain

134

)

135

)

136

137

# Streaming config with advanced voice options

138

streaming_config = StreamingSynthesizeConfig(

139

voice=VoiceSelectionParams(

140

language_code="en-US",

141

name="en-US-Neural2-A",

142

advanced_voice_options=texttospeech.AdvancedVoiceOptions(

143

low_latency_journey_synthesis=True # Enable low latency

144

)

145

),

146

audio_config=StreamingAudioConfig(

147

audio_encoding=AudioEncoding.LINEAR16,

148

sample_rate_hertz=16000 # Lower rate for reduced latency

149

)

150

)

151

```

152

153

### StreamingAudioConfig

154

155

```api { .api }

156

class StreamingAudioConfig:

157

"""Description of the desired output audio data for streaming.

158

159

Parameters:

160

- audio_encoding (AudioEncoding): Required. Format of audio byte stream.

161

Streaming supports PCM, ALAW, MULAW and OGG_OPUS only.

162

- sample_rate_hertz (int): Optional. Synthesis sample rate in hertz.

163

- speaking_rate (float): Optional. Speaking rate/speed in range [0.25, 2.0].

164

1.0 is normal speed, 2.0 is twice as fast, 0.5 is half speed.

165

"""

166

def __init__(self, audio_encoding, sample_rate_hertz=None, speaking_rate=None): ...

167

```

168

169

```api { .api }

170

from google.cloud.texttospeech import StreamingAudioConfig, AudioEncoding

171

172

# Basic streaming audio configuration

173

audio_config = StreamingAudioConfig(

174

audio_encoding=AudioEncoding.LINEAR16, # Required: audio format

175

sample_rate_hertz=22050 # Optional: sample rate

176

)

177

178

# Advanced streaming audio configuration

179

audio_config = StreamingAudioConfig(

180

audio_encoding=AudioEncoding.OGG_OPUS, # Compressed format for streaming

181

sample_rate_hertz=48000,

182

speaking_rate=0.9 # Slightly slower speech

183

)

184

185

# Low-latency configuration

186

low_latency_config = StreamingAudioConfig(

187

audio_encoding=AudioEncoding.LINEAR16,

188

sample_rate_hertz=16000, # Lower sample rate

189

speaking_rate=1.0 # Normal rate

190

)

191

```

192

193

### StreamingSynthesisInput

194

195

```api { .api }

196

class StreamingSynthesisInput:

197

"""Input to be synthesized in streaming requests.

198

199

This uses oneof fields - only one can be set at a time.

200

201

Parameters:

202

- text (str): Raw text to be synthesized. Recommended to use complete sentences.

203

- markup (str): Markup for HD voices specifically. Cannot be used with other voices.

204

- prompt (str): System instruction for controllable voice models only.

205

"""

206

def __init__(self, text=None, markup=None, prompt=None): ...

207

```

208

209

```api { .api }

210

from google.cloud.texttospeech import StreamingSynthesisInput

211

212

# Text input for streaming

213

text_input = StreamingSynthesisInput(

214

text="This is a chunk of text to be synthesized."

215

)

216

217

# Markup input for streaming (HD voices only)

218

markup_input = StreamingSynthesisInput(

219

markup="Markup content for HD voices specifically."

220

)

221

222

# Prompt input for controllable voice models

223

prompt_input = StreamingSynthesisInput(

224

prompt="System instruction for controllable voice models."

225

)

226

227

# Note: StreamingSynthesisInput uses oneof fields - only one can be set at a time

228

```

229

230

## Request and Response Types

231

232

### StreamingSynthesizeRequest

233

234

```api { .api }

235

class StreamingSynthesizeRequest:

236

"""Request message for StreamingSynthesize method.

237

238

Uses oneof fields - only one can be set at a time.

239

First message must contain streaming_config, subsequent messages contain input.

240

241

Parameters:

242

- streaming_config (StreamingSynthesizeConfig): Configuration for first request only.

243

- input (StreamingSynthesisInput): Input text/markup for subsequent requests.

244

"""

245

def __init__(self, streaming_config=None, input=None): ...

246

```

247

248

```api { .api }

249

from google.cloud.texttospeech import (

250

StreamingSynthesizeRequest,

251

StreamingSynthesizeConfig,

252

StreamingSynthesisInput

253

)

254

255

# Configuration request (first request in stream)

256

config_request = StreamingSynthesizeRequest(

257

streaming_config=StreamingSynthesizeConfig(

258

voice=texttospeech.VoiceSelectionParams(language_code="en-US"),

259

audio_config=texttospeech.StreamingAudioConfig(

260

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

261

sample_rate_hertz=22050

262

)

263

)

264

)

265

266

# Input request (subsequent requests)

267

input_request = StreamingSynthesizeRequest(

268

input=StreamingSynthesisInput(text="Text to synthesize")

269

)

270

271

# Markup input request (for HD voices)

272

markup_request = StreamingSynthesizeRequest(

273

input=StreamingSynthesisInput(

274

markup='Markup content with specific formatting for HD voices'

275

)

276

)

277

```

278

279

### StreamingSynthesizeResponse

280

281

```api { .api }

282

from google.cloud.texttospeech import StreamingSynthesizeResponse

283

284

# Response processing

285

def process_streaming_response(response: StreamingSynthesizeResponse):

286

"""Process individual streaming response."""

287

288

# Check for audio content

289

if response.audio_content:

290

audio_size = len(response.audio_content)

291

print(f"Received audio chunk: {audio_size} bytes")

292

return response.audio_content

293

294

# Handle other response fields

295

if hasattr(response, 'error') and response.error:

296

print(f"Streaming error: {response.error}")

297

298

return None

299

300

# Example response handling

301

def handle_streaming_responses(response_iterator):

302

"""Handle complete streaming response sequence."""

303

audio_chunks = []

304

total_chunks = 0

305

total_bytes = 0

306

307

for response in response_iterator:

308

audio_chunk = process_streaming_response(response)

309

if audio_chunk:

310

audio_chunks.append(audio_chunk)

311

total_chunks += 1

312

total_bytes += len(audio_chunk)

313

314

print(f"Streaming complete: {total_chunks} chunks, {total_bytes} bytes total")

315

return b''.join(audio_chunks)

316

```

317

318

## Practical Streaming Examples

319

320

### Real-Time Text Processing

321

322

```api { .api }

323

import threading

324

import queue

325

import time

326

from google.cloud import texttospeech

327

328

class RealTimeTextToSpeech:

329

"""Real-time text-to-speech streaming processor."""

330

331

def __init__(self, language_code="en-US", voice_name=None):

332

self.client = texttospeech.TextToSpeechClient()

333

self.text_queue = queue.Queue()

334

self.audio_queue = queue.Queue()

335

self.is_running = False

336

337

# Configure streaming

338

self.config = texttospeech.StreamingSynthesizeConfig(

339

voice=texttospeech.VoiceSelectionParams(

340

language_code=language_code,

341

name=voice_name or "en-US-Neural2-A",

342

advanced_voice_options=texttospeech.AdvancedVoiceOptions(

343

low_latency_journey_synthesis=True

344

)

345

),

346

audio_config=texttospeech.StreamingAudioConfig(

347

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

348

sample_rate_hertz=16000 # Lower rate for real-time

349

)

350

)

351

352

def start_streaming(self):

353

"""Start the streaming synthesis thread."""

354

self.is_running = True

355

self.streaming_thread = threading.Thread(target=self._stream_worker)

356

self.streaming_thread.start()

357

358

def stop_streaming(self):

359

"""Stop streaming synthesis."""

360

self.is_running = False

361

self.text_queue.put(None) # Sentinel to end stream

362

if hasattr(self, 'streaming_thread'):

363

self.streaming_thread.join()

364

365

def add_text(self, text: str):

366

"""Add text to synthesis queue."""

367

if self.is_running:

368

self.text_queue.put(text)

369

370

def get_audio(self, timeout: float = 1.0):

371

"""Get synthesized audio chunk."""

372

try:

373

return self.audio_queue.get(timeout=timeout)

374

except queue.Empty:

375

return None

376

377

def _stream_worker(self):

378

"""Background streaming worker."""

379

def request_generator():

380

# Send configuration first

381

yield texttospeech.StreamingSynthesizeRequest(

382

streaming_config=self.config

383

)

384

385

# Send text inputs as they arrive

386

while self.is_running:

387

try:

388

text = self.text_queue.get(timeout=1.0)

389

if text is None: # Sentinel to end

390

break

391

392

yield texttospeech.StreamingSynthesizeRequest(

393

input=texttospeech.StreamingSynthesisInput(text=text)

394

)

395

except queue.Empty:

396

continue

397

398

try:

399

# Start streaming

400

responses = self.client.streaming_synthesize(request_generator())

401

402

# Process responses

403

for response in responses:

404

if response.audio_content and self.is_running:

405

self.audio_queue.put(response.audio_content)

406

407

except Exception as e:

408

print(f"Streaming error: {e}")

409

finally:

410

self.audio_queue.put(None) # Signal end of audio

411

412

# Usage example

413

tts_stream = RealTimeTextToSpeech()

414

tts_stream.start_streaming()

415

416

# Add text for synthesis

417

tts_stream.add_text("Hello, this is real-time synthesis.")

418

tts_stream.add_text("Each text chunk is processed immediately.")

419

tts_stream.add_text("Great for interactive applications!")

420

421

# Collect audio chunks

422

audio_chunks = []

423

while True:

424

audio_chunk = tts_stream.get_audio()

425

if audio_chunk is None:

426

break

427

audio_chunks.append(audio_chunk)

428

print(f"Got audio chunk: {len(audio_chunk)} bytes")

429

430

tts_stream.stop_streaming()

431

432

# Combine all audio

433

complete_audio = b''.join(audio_chunks)

434

with open("realtime_output.wav", "wb") as f:

435

f.write(complete_audio)

436

```

437

438

### Interactive Conversation Streaming

439

440

```api { .api }

441

import asyncio

442

from google.cloud import texttospeech

443

444

class ConversationSynthesizer:

445

"""Interactive conversation streaming synthesis."""

446

447

def __init__(self):

448

self.client = texttospeech.TextToSpeechClient()

449

450

def synthesize_conversation(self, conversation_parts: list, output_file: str):

451

"""Synthesize conversation with different voices for different speakers."""

452

453

# Voice configurations for different speakers

454

speaker_configs = {

455

"speaker1": texttospeech.StreamingSynthesizeConfig(

456

voice=texttospeech.VoiceSelectionParams(

457

language_code="en-US",

458

name="en-US-Neural2-A" # Female voice

459

),

460

audio_config=texttospeech.StreamingAudioConfig(

461

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

462

sample_rate_hertz=22050

463

)

464

),

465

"speaker2": texttospeech.StreamingSynthesizeConfig(

466

voice=texttospeech.VoiceSelectionParams(

467

language_code="en-US",

468

name="en-US-Neural2-C" # Male voice

469

),

470

audio_config=texttospeech.StreamingAudioConfig(

471

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

472

sample_rate_hertz=22050

473

)

474

)

475

}

476

477

all_audio_chunks = []

478

479

# Process each speaker separately for voice consistency

480

for speaker_id, config in speaker_configs.items():

481

speaker_parts = [part for part in conversation_parts

482

if part.get('speaker') == speaker_id]

483

484

if not speaker_parts:

485

continue

486

487

def request_generator():

488

# Configuration

489

yield texttospeech.StreamingSynthesizeRequest(

490

streaming_config=config

491

)

492

493

# Speaker's dialogue parts

494

for part in speaker_parts:

495

yield texttospeech.StreamingSynthesizeRequest(

496

input=texttospeech.StreamingSynthesisInput(

497

text=part['text']

498

)

499

)

500

501

# Collect audio for this speaker

502

responses = self.client.streaming_synthesize(request_generator())

503

speaker_audio = []

504

505

for response in responses:

506

if response.audio_content:

507

speaker_audio.append(response.audio_content)

508

509

# Store with timing information

510

for i, part in enumerate(speaker_parts):

511

part['audio_data'] = b''.join(speaker_audio) if i == 0 else b''

512

513

# Reconstruct conversation in original order

514

final_audio = []

515

for part in conversation_parts:

516

if 'audio_data' in part and part['audio_data']:

517

final_audio.append(part['audio_data'])

518

519

# Save complete conversation

520

with open(output_file, "wb") as f:

521

f.write(b''.join(final_audio))

522

523

return output_file

524

525

# Usage example

526

conversation = [

527

{"speaker": "speaker1", "text": "Hello! How are you today?"},

528

{"speaker": "speaker2", "text": "I'm doing great, thanks for asking!"},

529

{"speaker": "speaker1", "text": "That's wonderful to hear. What are your plans?"},

530

{"speaker": "speaker2", "text": "I'm planning to work on some exciting projects."}

531

]

532

533

synthesizer = ConversationSynthesizer()

534

output_file = synthesizer.synthesize_conversation(conversation, "conversation.wav")

535

print(f"Conversation saved to {output_file}")

536

```

537

538

### Chunked Text Streaming

539

540

```api { .api }

541

def stream_long_text(text: str, chunk_size: int = 100):

542

"""Stream long text by breaking it into manageable chunks."""

543

import re

544

545

client = texttospeech.TextToSpeechClient()

546

547

# Configure streaming for long content

548

config = texttospeech.StreamingSynthesizeConfig(

549

voice=texttospeech.VoiceSelectionParams(

550

language_code="en-US",

551

name="en-US-Wavenet-A"

552

),

553

audio_config=texttospeech.StreamingAudioConfig(

554

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

555

sample_rate_hertz=22050

556

)

557

)

558

559

# Smart text chunking (respect sentence boundaries)

560

def smart_chunk_text(text: str, max_size: int):

561

"""Break text into chunks at sentence boundaries when possible."""

562

sentences = re.split(r'(?<=[.!?])\s+', text)

563

chunks = []

564

current_chunk = ""

565

566

for sentence in sentences:

567

if len(current_chunk + sentence) <= max_size:

568

current_chunk += sentence + " "

569

else:

570

if current_chunk:

571

chunks.append(current_chunk.strip())

572

current_chunk = sentence + " "

573

574

if current_chunk:

575

chunks.append(current_chunk.strip())

576

577

return chunks

578

579

# Create text chunks

580

text_chunks = smart_chunk_text(text, chunk_size)

581

582

def request_generator():

583

# Configuration request

584

yield texttospeech.StreamingSynthesizeRequest(streaming_config=config)

585

586

# Send text chunks

587

for i, chunk in enumerate(text_chunks):

588

print(f"Streaming chunk {i+1}/{len(text_chunks)}: {len(chunk)} chars")

589

yield texttospeech.StreamingSynthesizeRequest(

590

input=texttospeech.StreamingSynthesisInput(text=chunk)

591

)

592

593

# Stream and collect results

594

responses = client.streaming_synthesize(request_generator())

595

596

audio_chunks = []

597

chunk_count = 0

598

599

for response in responses:

600

if response.audio_content:

601

chunk_count += 1

602

audio_chunks.append(response.audio_content)

603

print(f"Received audio chunk {chunk_count}: {len(response.audio_content)} bytes")

604

605

return b''.join(audio_chunks)

606

607

# Usage with long text

608

long_text = """

609

This is a very long piece of text that demonstrates streaming synthesis

610

with automatic chunking. The system will break this text into smaller

611

pieces and stream them to the Text-to-Speech API. This approach is useful

612

for processing long documents, articles, or books where you want to start

613

receiving audio output before the entire text is processed. The streaming

614

approach also helps manage memory usage and provides better user experience

615

for real-time applications.

616

"""

617

618

audio_data = stream_long_text(long_text, chunk_size=80)

619

with open("streamed_long_text.wav", "wb") as f:

620

f.write(audio_data)

621

```

622

623

## Performance Optimization

624

625

### Low-Latency Streaming

626

627

```api { .api }

628

def create_low_latency_stream_config():

629

"""Create optimized configuration for minimal latency."""

630

631

return texttospeech.StreamingSynthesizeConfig(

632

voice=texttospeech.VoiceSelectionParams(

633

language_code="en-US",

634

name="en-US-Standard-A", # Standard voices have lower latency

635

advanced_voice_options=texttospeech.AdvancedVoiceOptions(

636

low_latency_journey_synthesis=True

637

)

638

),

639

audio_config=texttospeech.StreamingAudioConfig(

640

audio_encoding=texttospeech.AudioEncoding.LINEAR16, # Uncompressed

641

sample_rate_hertz=16000, # Lower sample rate

642

speaking_rate=1.1 # Slightly faster speech

643

)

644

)

645

646

def optimized_streaming_synthesis(text_parts: list):

647

"""Optimized streaming for real-time applications."""

648

client = texttospeech.TextToSpeechClient()

649

650

config = create_low_latency_stream_config()

651

652

def fast_request_generator():

653

yield texttospeech.StreamingSynthesizeRequest(streaming_config=config)

654

655

for text in text_parts:

656

# Send smaller chunks for faster processing

657

if len(text) > 50:

658

# Break into smaller pieces

659

words = text.split()

660

chunk_size = 10 # words per chunk

661

for i in range(0, len(words), chunk_size):

662

chunk = " ".join(words[i:i + chunk_size])

663

yield texttospeech.StreamingSynthesizeRequest(

664

input=texttospeech.StreamingSynthesisInput(text=chunk)

665

)

666

else:

667

yield texttospeech.StreamingSynthesizeRequest(

668

input=texttospeech.StreamingSynthesisInput(text=text)

669

)

670

671

# Process with timing

672

import time

673

start_time = time.time()

674

675

responses = client.streaming_synthesize(fast_request_generator())

676

first_response_time = None

677

audio_chunks = []

678

679

for response in responses:

680

if response.audio_content:

681

if first_response_time is None:

682

first_response_time = time.time()

683

print(f"First audio received in: {first_response_time - start_time:.2f}s")

684

685

audio_chunks.append(response.audio_content)

686

687

total_time = time.time() - start_time

688

print(f"Total streaming time: {total_time:.2f}s")

689

690

return b''.join(audio_chunks)

691

```

692

693

### Error Handling for Streaming

694

695

```api { .api }

696

from google.api_core import exceptions

697

import logging

698

699

def robust_streaming_synthesis(text_parts: list, max_retries: int = 3):

700

"""Streaming synthesis with comprehensive error handling."""

701

702

client = texttospeech.TextToSpeechClient()

703

704

config = texttospeech.StreamingSynthesizeConfig(

705

voice=texttospeech.VoiceSelectionParams(language_code="en-US"),

706

audio_config=texttospeech.StreamingAudioConfig(

707

audio_encoding=texttospeech.AudioEncoding.LINEAR16,

708

sample_rate_hertz=22050

709

)

710

)

711

712

for attempt in range(max_retries):

713

try:

714

def request_generator():

715

yield texttospeech.StreamingSynthesizeRequest(streaming_config=config)

716

717

for text in text_parts:

718

yield texttospeech.StreamingSynthesizeRequest(

719

input=texttospeech.StreamingSynthesisInput(text=text)

720

)

721

722

# Attempt streaming

723

responses = client.streaming_synthesize(request_generator())

724

725

audio_chunks = []

726

for response in responses:

727

if response.audio_content:

728

audio_chunks.append(response.audio_content)

729

730

return b''.join(audio_chunks)

731

732

except exceptions.DeadlineExceeded as e:

733

logging.warning(f"Streaming timeout (attempt {attempt + 1}): {e}")

734

if attempt == max_retries - 1:

735

raise

736

737

except exceptions.ResourceExhausted as e:

738

logging.warning(f"Rate limit exceeded (attempt {attempt + 1}): {e}")

739

if attempt == max_retries - 1:

740

raise

741

# Wait before retry

742

import time

743

time.sleep(2 ** attempt) # Exponential backoff

744

745

except exceptions.ServiceUnavailable as e:

746

logging.warning(f"Service unavailable (attempt {attempt + 1}): {e}")

747

if attempt == max_retries - 1:

748

raise

749

import time

750

time.sleep(1)

751

752

except Exception as e:

753

logging.error(f"Unexpected streaming error: {e}")

754

raise

755

756

raise RuntimeError(f"Streaming failed after {max_retries} attempts")

757

758

# Usage with error handling

759

try:

760

text_parts = [

761

"This is the first part of the streaming text.",

762

"Here's the second part with more content.",

763

"And finally, this is the conclusion."

764

]

765

766

audio_result = robust_streaming_synthesis(text_parts)

767

print(f"Successfully generated {len(audio_result)} bytes of audio")

768

769

except Exception as e:

770

print(f"Streaming synthesis failed: {e}")

771

```