如何用Python与VS Code在终端直接运行MP4视频及图片
在VS Code终端内高质量播放MP4与展示图片的实现方案
一、前提准备
确保安装必要的Python库和工具:
pillow:处理图片与视频帧rich:终端富文本渲染(支持True Color与高质量图片展示)opencv-python:读取视频帧(或用ffmpeg-python提升性能)ffmpeg:若使用ffmpeg-python,需通过系统包管理器安装(Windows用choco、Mac用brew、Linux用apt)
安装命令:
pip install pillow rich opencv-python ffmpeg-python
二、高质量图片展示实现
用rich库直接在VS Code终端渲染图片,支持True Color,画质清晰:
from rich.console import Console from rich.image import Image console = Console() # 加载本地图片 img = Image.open("your_image.jpg") # 按终端宽度自适应缩放,保留原比例 console.print(img) # 自定义展示宽度 # console.print(img, width=80)
三、MP4视频播放优化(解决方块像素问题)
之前的画质差多因帧缩放过度、颜色深度不足、渲染算法粗糙,以下方案从这几点针对性优化:
1. 核心优化方向
- 严格保留视频宽高比例,避免强制拉伸
- 启用VS Code终端的True Color(24位色)支持
- 使用 Lanczos 插值算法缩放帧,保证细节
- 匹配原视频帧率,避免丢帧卡顿
2. 完整代码实现(基于opencv)
import cv2 from rich.console import Console from rich.image import Image from PIL import Image as PILImage import numpy as np import time console = Console() def play_video_in_terminal(video_path, target_width=None): cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print("无法打开视频文件") return # 获取原视频参数 fps = cap.get(cv2.CAP_PROP_FPS) frame_delay = 1 / fps # 默认用终端宽度作为目标宽度 target_width = target_width or console.width while cap.isOpened(): ret, frame = cap.read() if not ret: break # 转换颜色空间:OpenCV的BGR转PIL的RGB frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_frame = PILImage.fromarray(frame_rgb) # 计算等比例缩放后的高度 width_ratio = target_width / pil_frame.width target_height = int(pil_frame.height * width_ratio) # 用Lanczos插值缩放,最大化保留画质 pil_frame = pil_frame.resize((target_width, target_height), PILImage.Resampling.LANCZOS) # 清除上一帧并渲染当前帧 console.clear() console.print(Image(pil_frame)) # 控制播放帧率 time.sleep(frame_delay) cap.release() # 调用播放 play_video_in_terminal("your_video.mp4")
3. 额外优化建议
- 若终端颜色显示异常,在VS Code的
settings.json中添加配置:"terminal.integrated.enableTrueColor": true - 大分辨率视频可预先用ffmpeg转码,减少实时缩放压力:
ffmpeg -i input.mp4 -vf scale=1280:-1 -c:v libx264 -crf 23 output.mp4 - 若追求更高性能,改用
ffmpeg-python直接提取帧(代码如下):
import ffmpeg from rich.console import Console from rich.image import Image from PIL import Image as PILImage import time import numpy as np console = Console() def play_video_with_ffmpeg(video_path, target_width=None): probe = ffmpeg.probe(video_path) video_stream = next((s for s in probe['streams'] if s['codec_type'] == 'video'), None) if not video_stream: print("未找到视频流") return fps = eval(video_stream['r_frame_rate']) frame_delay = 1 / fps target_width = target_width or console.width target_height = int(target_width * int(video_stream['height']) / int(video_stream['width'])) # 用ffmpeg提取RGB帧流,指定Lanczos缩放算法 process = ( ffmpeg .input(video_path) .output('pipe:', format='rawvideo', pix_fmt='rgb24', s=f"{target_width}x{target_height}", sws_flags='lanczos') .run_async(pipe_stdout=True) ) while True: frame_size = target_width * target_height * 3 in_bytes = process.stdout.read(frame_size) if not in_bytes: break # 转换为PIL图片并渲染 frame = np.frombuffer(in_bytes, np.uint8).reshape((target_height, target_width, 3)) pil_frame = PILImage.fromarray(frame) console.clear() console.print(Image(pil_frame)) time.sleep(frame_delay) process.wait() play_video_with_ffmpeg("your_video.mp4")
内容的提问来源于stack exchange,提问作者IndieMultiCraft
相关产品推荐
相关产品推荐

