mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Stream Timestamp Fixes (#22912)
* reset timestamps for streams that do not do so when first requested * update inline comments to be more descriptive
This commit is contained in:
parent
590eead128
commit
43487aa0d6
@ -85,7 +85,7 @@ class M3U8Renderer:
|
|||||||
for sequence in segments:
|
for sequence in segments:
|
||||||
segment = track.get_segment(sequence)
|
segment = track.get_segment(sequence)
|
||||||
playlist.extend([
|
playlist.extend([
|
||||||
"#EXTINF:{:.04},".format(float(segment.duration)),
|
"#EXTINF:{:.04f},".format(float(segment.duration)),
|
||||||
"./segment/{}.ts".format(segment.sequence),
|
"./segment/{}.ts".format(segment.sequence),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -55,10 +55,16 @@ def stream_worker(hass, stream, quit_event):
|
|||||||
|
|
||||||
audio_frame = generate_audio_frame()
|
audio_frame = generate_audio_frame()
|
||||||
|
|
||||||
outputs = {}
|
|
||||||
first_packet = True
|
first_packet = True
|
||||||
|
# Holds the buffers for each stream provider
|
||||||
|
outputs = {}
|
||||||
|
# Keep track of the number of segments we've processed
|
||||||
sequence = 1
|
sequence = 1
|
||||||
|
# Holds the generated silence that needs to be muxed into the output
|
||||||
audio_packets = {}
|
audio_packets = {}
|
||||||
|
# The presentation timestamp of the first video packet we recieve
|
||||||
|
first_pts = 0
|
||||||
|
# The decoder timestamp of the latest packet we processed
|
||||||
last_dts = None
|
last_dts = None
|
||||||
|
|
||||||
while not quit_event.is_set():
|
while not quit_event.is_set():
|
||||||
@ -82,10 +88,18 @@ def stream_worker(hass, stream, quit_event):
|
|||||||
continue
|
continue
|
||||||
last_dts = packet.dts
|
last_dts = packet.dts
|
||||||
|
|
||||||
|
# Reset timestamps from a 0 time base for this stream
|
||||||
|
packet.dts -= first_pts
|
||||||
|
packet.pts -= first_pts
|
||||||
|
|
||||||
# Reset segment on every keyframe
|
# Reset segment on every keyframe
|
||||||
if packet.is_keyframe:
|
if packet.is_keyframe:
|
||||||
# Save segment to outputs
|
# Calculate the segment duration by multiplying the presentation
|
||||||
|
# timestamp by the time base, which gets us total seconds.
|
||||||
|
# By then dividing by the seqence, we can calculate how long
|
||||||
|
# each segment is, assuming the stream starts from 0.
|
||||||
segment_duration = (packet.pts * packet.time_base) / sequence
|
segment_duration = (packet.pts * packet.time_base) / sequence
|
||||||
|
# Save segment to outputs
|
||||||
for fmt, buffer in outputs.items():
|
for fmt, buffer in outputs.items():
|
||||||
buffer.output.close()
|
buffer.output.close()
|
||||||
del audio_packets[buffer.astream]
|
del audio_packets[buffer.astream]
|
||||||
@ -112,6 +126,12 @@ def stream_worker(hass, stream, quit_event):
|
|||||||
|
|
||||||
# First video packet tends to have a weird dts/pts
|
# First video packet tends to have a weird dts/pts
|
||||||
if first_packet:
|
if first_packet:
|
||||||
|
# If we are attaching to a live stream that does not reset
|
||||||
|
# timestamps for us, we need to do it ourselves by recording
|
||||||
|
# the first presentation timestamp and subtracting it from
|
||||||
|
# subsequent packets we recieve.
|
||||||
|
if (packet.pts * packet.time_base) > 1:
|
||||||
|
first_pts = packet.pts
|
||||||
packet.dts = 0
|
packet.dts = 0
|
||||||
packet.pts = 0
|
packet.pts = 0
|
||||||
first_packet = False
|
first_packet = False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user