@@ -328,9 +328,18 @@ async def remove_app_fe_setting(req: AppFeSettingDelReq):
328328
329329 @app .get (f"{ api_base } /version" , dependencies = [Depends (verify_secret )])
330330 async def get_version ():
331+ av_version = None
332+ try :
333+ import av as _av
334+ av_version = getattr (_av , "__version__" , None )
335+ except Exception :
336+ # av (PyAV) not installed or failed to import
337+ av_version = None
338+
331339 return {
332340 "hash" : get_current_commit_hash (),
333341 "tag" : get_current_tag (),
342+ "av_version" : av_version ,
334343 }
335344
336345 class DeleteFilesReq (BaseModel ):
@@ -649,16 +658,34 @@ async def video_cover(path: str, mt: str):
649658 if not is_media_file (path ):
650659 raise HTTPException (status_code = 400 , detail = f"{ path } is not a video file" )
651660 # 如果缓存文件不存在,则生成缩略图并保存
652-
653- import imageio .v3 as iio
654- frame = iio .imread (
655- path ,
656- index = 16 ,
657- plugin = "pyav" ,
658- )
659-
660- os .makedirs (cache_dir , exist_ok = True )
661- iio .imwrite (cache_path ,frame , extension = ".webp" )
661+ try :
662+ import imageio .v3 as iio
663+ logger .info (
664+ "Generating video cover thumbnail: path=%s, mt=%s, cache_path=%s" ,
665+ path ,
666+ mt ,
667+ cache_path ,
668+ )
669+ frame = iio .imread (
670+ path ,
671+ index = 16 ,
672+ plugin = "pyav" ,
673+ )
674+
675+ os .makedirs (cache_dir , exist_ok = True )
676+ iio .imwrite (cache_path , frame , extension = ".webp" )
677+ logger .info ("Saved video cover thumbnail: %s" , cache_path )
678+ except Exception as e :
679+ # record full stack trace and contextual info in English
680+ logger .exception (
681+ "Failed to generate video cover for path=%s mt=%s cache_dir=%s: %s" ,
682+ path ,
683+ mt ,
684+ cache_dir ,
685+ e ,
686+ )
687+ # return a clear HTTP error (detail contains exception message)
688+ raise HTTPException (status_code = 500 , detail = f"Failed to generate video cover: { e } " )
662689
663690 # 返回缓存文件
664691 return FileResponse (
0 commit comments