为何代码将.jpg图片识别为视频?如何修复该问题?
问题原因
当你通过ffmpeg.probe指定select_streams=stream(推测此处stream为'v')查询.jpg文件时,ffmpeg会将静态图片解析为单帧视频流,返回的元数据中codec_type会被标记为'video'。而你的is_video()方法仅通过codec_type判断,未结合文件实际格式做二次验证,这就导致了误判。
修复方案
方案1:结合FFmpeg格式信息验证(推荐)
通过FFmpeg返回的格式信息排除图像类文件,再判断视频流:
- 调整元数据获取逻辑,保留完整的探测结果:
# 获取完整的媒体探测数据,不提前筛选流 full_probe = ffmpeg.probe(self.path) # 提取视频流元数据(供其他功能使用) self.video_metadata = next((stream for stream in full_probe['streams'] if stream['codec_type'] == 'video'), None) # 保存格式信息用于类型判断 self.format_info = full_probe['format']
- 修改
is_video()方法:
def is_video(self) -> bool: try: # 先排除常见图像格式 image_formats = {'image2', 'jpeg', 'png', 'bmp'} if self.format_info['format_name'] in image_formats: return False # 再验证是否存在有效视频流 res = self.video_metadata is not None and self.video_metadata['codec_type'] == 'video' logger.info(f"Video.is_video() -> {res}") return res except Exception as e: logger.error(f"检查视频类型出错: {e}") return False
方案2:通过文件扩展名快速过滤
如果对准确性要求不极致,可先通过扩展名排除图片:
def is_video(self) -> bool: # 排除常见图片扩展名 image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp'} if any(self.path.lower().endswith(ext) for ext in image_extensions): return False # 执行原有判断逻辑 try: res = self.video_metadata['codec_type'] == 'video' logger.info(f"Video.is_video() -> {res}") return res except Exception as e: logger.error(f"检查视频类型出错: {e}") return False
方案3:验证视频流的帧数量或时长
若需区分单帧视频和静态图片,可检查视频流的帧数量或时长:
def is_video(self) -> bool: try: if self.video_metadata['codec_type'] != 'video': return False # 单帧图片解析的视频流通常帧数量为1、时长接近0 nb_frames = int(self.video_metadata.get('nb_frames', 0)) duration = float(self.video_metadata.get('duration', 0)) if nb_frames <= 1 and duration < 0.1: return False res = True logger.info(f"Video.is_video() -> {res}") return res except Exception as e: logger.error(f"检查视频类型出错: {e}") return False
内容的提问来源于stack exchange,提问作者user20317520
相关产品推荐
相关产品推荐

