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