fix : ffmpeg_slice_media 根据seek_head处理切割点时间为相对时间, 添加了实际获取片段和请求开始时间的diff差值
This commit is contained in:
parent
2551702443
commit
0f66ac03c2
|
|
@ -454,21 +454,17 @@ class VideoUtils:
|
|||
seek_tail = media_markers[-1].end.total_seconds()
|
||||
duration = seek_tail - seek_head
|
||||
logger.info(f"Only using {seek_head}s --> {seek_tail}s = {duration}s")
|
||||
local_m3u8_path, temp_dir = await VideoUtils.convert_m3u8_to_local_source(media_path, head=seek_head,
|
||||
local_m3u8_path, temp_dir, diff = await VideoUtils.convert_m3u8_to_local_source(media_path, head=seek_head,
|
||||
tail=seek_tail)
|
||||
logger.info(f"local_playlist: {local_m3u8_path}")
|
||||
|
||||
for segment in media_markers:
|
||||
segment.start = segment.start - timedelta(seconds=seek_head)
|
||||
segment.end = segment.end - timedelta(seconds=seek_head)
|
||||
segment.start = segment.start - timedelta(seconds=seek_head) + diff
|
||||
segment.end = segment.end - timedelta(seconds=seek_head) + diff
|
||||
logger.info(f"Only using {seek_head}s --> {seek_tail}s = {duration}s")
|
||||
ffmpeg_cmd.input(local_m3u8_path,
|
||||
# ss=seek_head,
|
||||
t=duration,
|
||||
protocol_whitelist="file,http,https,tcp,tls")
|
||||
# reconnect="1", # 自动重连
|
||||
# reconnect_streamed="1",
|
||||
# reconnect_delay_max="5")
|
||||
|
||||
filter_complex: List[str] = []
|
||||
temp_outputs: List[str] = []
|
||||
|
|
@ -478,8 +474,8 @@ class VideoUtils:
|
|||
|
||||
metadata = VideoUtils.ffprobe_media_metadata(media_path)
|
||||
for index, marker in enumerate(media_markers):
|
||||
start = marker.start.total_seconds() - seek_head
|
||||
end = marker.end.total_seconds() - seek_head
|
||||
start = marker.start.total_seconds()
|
||||
end = marker.end.total_seconds()
|
||||
|
||||
# 处理指定的输出分辨率
|
||||
if options.width and options.height:
|
||||
|
|
@ -562,7 +558,7 @@ class VideoUtils:
|
|||
@staticmethod
|
||||
async def convert_m3u8_to_local_source(media_stream_url: str,
|
||||
head: Optional[float] = None,
|
||||
tail: Optional[float] = None) -> tuple[str, str]:
|
||||
tail: Optional[float] = None) -> tuple[str, str, TimeDelta]:
|
||||
"""
|
||||
转换m3u8为本地来源
|
||||
"""
|
||||
|
|
@ -574,18 +570,28 @@ class VideoUtils:
|
|||
playlist = m3u8.load(media_stream_url)
|
||||
# duration = (tail - head) if head else None
|
||||
origin_time: datetime = playlist.segments[0].current_program_date_time
|
||||
logger.info(f"Start Timestamp: {origin_time}")
|
||||
# 2. 解析TS片段URL
|
||||
ts_urls: SegmentList[Segment] = SegmentList()
|
||||
duration = 0
|
||||
min_head = origin_time + timedelta(seconds=head)
|
||||
max_head = origin_time + timedelta(seconds=tail)
|
||||
logger.info(f"min: {min_head}, max: {max_head}")
|
||||
for segment in playlist.segments:
|
||||
if not head:
|
||||
head = 0
|
||||
if not tail:
|
||||
tail = 86400 # 使用24H时长替代♾️
|
||||
if origin_time + timedelta(
|
||||
seconds=head) <= segment.current_program_date_time <= origin_time + timedelta(seconds=tail):
|
||||
if min_head - timedelta(seconds=segment.duration) <= segment.current_program_date_time <= max_head:
|
||||
logger.info(f"duration: {segment.duration}, head: {segment.current_program_date_time}")
|
||||
duration += segment.duration
|
||||
ts_urls.append(segment)
|
||||
if len(ts_urls) > 0:
|
||||
delta = min_head - ts_urls[0].current_program_date_time
|
||||
diff = TimeDelta.from_timedelta(delta)
|
||||
else:
|
||||
diff = TimeDelta(seconds=0)
|
||||
logger.info(f"diff = {diff.total_seconds()}")
|
||||
# 3. 并行下载TS片段
|
||||
tasks = []
|
||||
playlist.segments = ts_urls
|
||||
|
|
@ -601,7 +607,7 @@ class VideoUtils:
|
|||
local_m3u8_path = os.path.join(temp_dir, "local.m3u8")
|
||||
playlist.dump(local_m3u8_path)
|
||||
|
||||
return local_m3u8_path, temp_dir
|
||||
return local_m3u8_path, temp_dir, diff
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
raise Exception(f"下载TS转换M3U8失败 {e}")
|
||||
|
|
@ -617,7 +623,7 @@ class VideoUtils:
|
|||
@staticmethod
|
||||
async def ffmpeg_convert_stream_media(media_stream_url: str, options: FFMPEGSliceOptions,
|
||||
output_path: Optional[str] = None) -> tuple[
|
||||
str, VideoMetadata] | None:
|
||||
str, VideoMetadata] | None:
|
||||
if not output_path:
|
||||
output_path = FileUtils.file_path_extend(media_stream_url, "convert")
|
||||
if not output_path.endswith(".mp4"):
|
||||
|
|
|
|||
Loading…
Reference in New Issue