MCPcopy Create free account
hub / github.com/Dispatcharr/Dispatcharr / fetch_stream

Function fetch_stream

apps/proxy/hls_proxy/server.py:678–797  ·  view source on GitHub ↗

Main streaming function that handles manifest updates and segment downloads. Args: fetcher: StreamFetcher instance to handle HTTP requests stop_event: Threading event to signal when to stop fetching start_sequence: Initial sequence number to start from

(fetcher: StreamFetcher, stop_event: threading.Event, start_sequence: int = 0)

Source from the content-addressed store, hash-verified

676 }
677
678def fetch_stream(fetcher: StreamFetcher, stop_event: threading.Event, start_sequence: int = 0):
679 """
680 Main streaming function that handles manifest updates and segment downloads.
681
682 Args:
683 fetcher: StreamFetcher instance to handle HTTP requests
684 stop_event: Threading event to signal when to stop fetching
685 start_sequence: Initial sequence number to start from
686
687 The function implements the core HLS fetching logic:
688 - Fetches and parses manifest files
689 - Downloads new segments when they become available
690 - Handles stream switches with proper discontinuity marking
691 - Maintains buffer state and segment sequence numbering
692 """
693 # Remove global stream_manager reference
694 retry_delay = 1
695 max_retry_delay = 8
696 last_segment_time = 0
697 buffer_initialized = False
698 manifest_update_needed = True
699 segment_duration = None
700
701 while not stop_event.is_set():
702 try:
703 now = time.time()
704
705 # Only update manifest when it's time for next segment
706 should_update = (
707 manifest_update_needed or
708 not segment_duration or
709 (last_segment_time and (now - last_segment_time) >= segment_duration * 0.8)
710 )
711
712 if should_update:
713 manifest_data, final_url = fetcher.download(fetcher.stream_url)
714 manifest = m3u8.loads(manifest_data.decode())
715
716 if not manifest.segments:
717 continue
718
719 with buffer_lock:
720 manifest_content = manifest_data.decode()
721 new_segments = {}
722
723 if fetcher.manager.switching_stream: # Use fetcher.manager instead of stream_manager
724 # Stream switch - only get latest segment
725 manifest_segments = [manifest.segments[-1]]
726 seq_start = fetcher.manager.next_sequence
727 max_segments = 1
728 logging.debug(f"Processing stream switch - getting latest segment at sequence {seq_start}")
729 elif not buffer_initialized:
730 # Initial buffer
731 manifest_segments = manifest.segments[-Config.INITIAL_SEGMENTS:]
732 seq_start = fetcher.manager.next_sequence
733 max_segments = Config.INITIAL_SEGMENTS
734 logging.debug(f"Starting initial buffer at sequence {seq_start}")
735 else:

Callers 1

_fetch_loopMethod · 0.85

Calls 6

verify_segmentFunction · 0.85
downloadMethod · 0.80
get_next_sequenceMethod · 0.80
getMethod · 0.45
setMethod · 0.45
waitMethod · 0.45

Tested by

no test coverage detected