Main fetch loop for stream data
(self)
| 465 | raise |
| 466 | |
| 467 | def fetch_loop(self): |
| 468 | """Main fetch loop for stream data""" |
| 469 | retry_delay = 1 |
| 470 | max_retry_delay = 8 |
| 471 | last_manifest_time = 0 |
| 472 | downloaded_segments = set() # Track downloaded segment URIs |
| 473 | |
| 474 | while self.manager.running: |
| 475 | try: |
| 476 | current_time = time.time() |
| 477 | |
| 478 | # Check manifest update timing |
| 479 | if last_manifest_time: |
| 480 | time_since_last = current_time - last_manifest_time |
| 481 | if time_since_last < (self.manager.target_duration * 0.5): |
| 482 | time.sleep(self.manager.target_duration * 0.5 - time_since_last) |
| 483 | continue |
| 484 | |
| 485 | # Get manifest data |
| 486 | manifest_data, final_url = self.download(self.manager.current_url) |
| 487 | manifest = m3u8.loads(manifest_data.decode()) |
| 488 | |
| 489 | # Update manifest info |
| 490 | if manifest.target_duration: |
| 491 | self.manager.target_duration = float(manifest.target_duration) |
| 492 | if manifest.version: |
| 493 | self.manager.manifest_version = manifest.version |
| 494 | |
| 495 | if not manifest.segments: |
| 496 | continue |
| 497 | |
| 498 | if self.manager.initial_buffering: |
| 499 | segments_to_fetch = [] |
| 500 | current_duration = 0.0 |
| 501 | successful_downloads = 0 # Initialize counter here |
| 502 | |
| 503 | # Start from the end of the manifest |
| 504 | for segment in reversed(manifest.segments): |
| 505 | current_duration += float(segment.duration) |
| 506 | segments_to_fetch.append(segment) |
| 507 | |
| 508 | # Stop when we have enough duration or hit max segments |
| 509 | if (current_duration >= Config.INITIAL_BUFFER_SECONDS or |
| 510 | len(segments_to_fetch) >= Config.MAX_INITIAL_SEGMENTS): |
| 511 | break |
| 512 | |
| 513 | # Reverse back to chronological order |
| 514 | segments_to_fetch.reverse() |
| 515 | |
| 516 | # Download initial segments |
| 517 | for segment in segments_to_fetch: |
| 518 | try: |
| 519 | segment_url = urljoin(final_url, segment.uri) |
| 520 | segment_data, _ = self.download(segment_url) |
| 521 | |
| 522 | validation = verify_segment(segment_data) |
| 523 | if validation.get('valid', False): |
| 524 | with self.buffer.lock: |
nothing calls this directly
no test coverage detected