fix : 修复hls直播转mp4缺少的一个参数
This commit is contained in:
parent
0f66ac03c2
commit
1920b4bd9d
|
|
@ -9,6 +9,7 @@ from loguru import logger
|
|||
import httpx
|
||||
from fastapi import APIRouter, UploadFile, Header, HTTPException, Depends
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import computed_field
|
||||
from starlette import status
|
||||
from starlette.responses import JSONResponse
|
||||
|
||||
|
|
@ -34,8 +35,18 @@ class BundleHeaders(BaseModel):
|
|||
x_baggage: str = Field(description="Sentry Transaction baggage", default=None)
|
||||
|
||||
|
||||
class GoogleAuthHeaders(BaseModel):
|
||||
Authorization: str = Field(description="Google Auth Bearer Token")
|
||||
|
||||
@computed_field(description="Google Auth Token")
|
||||
@property
|
||||
def auth_token(self) -> str:
|
||||
return self.Authorization[len("Bearer "):]
|
||||
|
||||
|
||||
@router.post("/upload",
|
||||
summary="上传文件到Google File",
|
||||
summary="上传文件到Google AI Studio提供的File API, 将被VertexAI新规范替代,统一使用Google CloudStorage存储",
|
||||
deprecated=True,
|
||||
description="上传文件到Google File, 换取Google File URI, 不同Google API Key之间的URI不互通, 最多可为每个项目存储 20 GB 的文件,每个文件的大小上限为 2 GB。文件会存储 48 小时")
|
||||
async def upload_file_multipart(file: UploadFile,
|
||||
headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
|
|
@ -80,6 +91,10 @@ async def upload_file_multipart(file: UploadFile,
|
|||
return JSONResponse(content=upload_response.json(), status_code=upload_response.status_code)
|
||||
|
||||
|
||||
@router.post("/vertex-ai/upload", summary="上传文件到Vertex AI可访问的Google cloud storage", )
|
||||
async def upload_file(file: UploadFile, headers: Annotated[GoogleAuthHeaders, Header()]):
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
@router.get("/status", summary="获取已上传文件的处理状态")
|
||||
async def uploaded_file_status(filename: str,
|
||||
headers: Annotated[GoogleAPIKeyHeaders, Header()]):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Union, Dict, Any
|
||||
from typing import Union, Dict, Any, BinaryIO
|
||||
|
||||
import backoff
|
||||
import httpx
|
||||
|
|
@ -126,3 +126,7 @@ class GoogleAuthUtils:
|
|||
data=params)
|
||||
response.raise_for_status()
|
||||
return GoogleAuthUtils.GoogleAuthResponse.model_validate_json(response.text)
|
||||
|
||||
# @staticmethod
|
||||
# async def google_upload_file(file_stream: BinaryIO, google_api_key: str, bucket_name: str):
|
||||
#
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ class VideoUtils:
|
|||
duration = seek_tail - seek_head
|
||||
logger.info(f"Only using {seek_head}s --> {seek_tail}s = {duration}s")
|
||||
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}")
|
||||
|
||||
for segment in media_markers:
|
||||
|
|
@ -557,13 +557,17 @@ 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, TimeDelta]:
|
||||
head: float = 0,
|
||||
tail: float = 86400, # 使用24H时长替代♾️
|
||||
temp_dir: str = None) -> tuple[str, str, TimeDelta]:
|
||||
"""
|
||||
转换m3u8为本地来源
|
||||
"""
|
||||
# 创建临时目录存储TS片段
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
if temp_dir:
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
else:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
from m3u8 import SegmentList, Segment
|
||||
try:
|
||||
# 1. 下载m3u8文件
|
||||
|
|
@ -578,10 +582,6 @@ class VideoUtils:
|
|||
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 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
|
||||
|
|
@ -600,13 +600,10 @@ class VideoUtils:
|
|||
playlist.is_endlist = True
|
||||
for url in ts_urls:
|
||||
tasks.append(VideoUtils.async_download_file(url.absolute_uri, f"{temp_dir}/{url.uri}"))
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
# 4. 修改m3u8文件指向本地TS片段
|
||||
local_m3u8_path = os.path.join(temp_dir, "local.m3u8")
|
||||
playlist.dump(local_m3u8_path)
|
||||
|
||||
return local_m3u8_path, temp_dir, diff
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
|
@ -631,7 +628,7 @@ class VideoUtils:
|
|||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
|
||||
try:
|
||||
local_m3u8_path, temp_dir = await VideoUtils.convert_m3u8_to_local_source(media_stream_url=media_stream_url)
|
||||
local_m3u8_path, temp_dir, diff = await VideoUtils.convert_m3u8_to_local_source(media_stream_url=media_stream_url)
|
||||
# 使用ffmpeg合并TS片段
|
||||
ffmpeg_cmd = VideoUtils.async_ffmpeg_init()
|
||||
ffmpeg_cmd.input(local_m3u8_path,
|
||||
|
|
|
|||
Loading…
Reference in New Issue