当前位置: 首页 > news >正文

K230基础-录放视频

第二十三章 录放视频-K230视频录制与回放能力

🎯 本章目标
掌握在 K230(CanMV 平台)上实现视频录制与回放的核心方法,学会将摄像头采集的图像帧保存为视频文件(如 MJPEG 流),并实现本地存储与回放,构建嵌入式监控、记录仪等应用。


1. 视频处理能力概述

1.1 K230 视频支持现状

  • ✅ 支持 摄像头实时采集
  • ✅ 支持 JPEG 图像编码(由摄像头硬件完成)
  • ✅ 支持 MJPEG 视频流(连续 JPEG 帧)
  • ❌ 不支持 H.264/HEVC 等高压缩编码
  • ✅ 支持 SD 卡存储
  • ❌ 无硬件视频编码器,依赖摄像头输出 JPEG

📌 结论
可通过 摄像头输出 MJPEG 流 + SD 卡存储 实现“类视频”录制。


2. 视频格式说明

2.1 MJPEG(Motion JPEG)

  • 将视频每一帧作为独立 JPEG 图像存储
  • 文件扩展名通常为 .avi.mjpeg
  • 优点:简单、兼容性好、无需复杂编码
  • 缺点:文件大、压缩率低

K230 最可行方案


3. 视频录制:将图像帧保存为 MJPEG

3.1 硬件准备

  • K230 开发板
  • 摄像头(OV2640 推荐)
  • SD 卡(≥8GB,Class 10)
  • FPIOA 映射 SPI 引脚(见 SPI 章节)

3.2 SD 卡挂载

import os
import sdcard
from machine import SPI, Pin
from fpioa_manager import fm# SPI 引脚定义
SCLK_PIN = 6
MOSI_PIN = 8
MISO_PIN = 9
CS_PIN   = 7# FPIOA 映射
fm.register(SCLK_PIN, fm.fpioa.SPI1_SCLK)
fm.register(MOSI_PIN, fm.fpioa.SPI1_D0)
fm.register(MISO_PIN, fm.fpioa.SPI1_D1)
fm.register(CS_PIN,   fm.fpioa.GPIOHS0)# 初始化 SPI
spi = SPI(SPI.SPI1, baudrate=20_000_000, polarity=0, phase=0)
cs = Pin(CS_PIN, Pin.OUT, value=1)# 挂载 SD 卡
sd = sdcard.SDCard(spi, cs)
os.mount(sd, "/sd")
print("SD 卡已挂载")

3.3 视频录制主程序

import sensor
import time
import os# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.JPEG)      # 必须使用 JPEG 格式
sensor.set_framesize(sensor.VGA)      # 640x480
sensor.skip_frames(time=2000)# 设置 JPEG 质量
sensor.set_quality(10)  # 1~63,越小质量越高print("开始视频录制...")# 创建视频目录
try:os.mkdir("/sd/video")
except:pass# 视频文件名
filename = "/sd/video/vid_%d.mjpeg" % time.time()
f = open(filename, "wb")# 录制时长(秒)
DURATION = 30
FPS = 10
INTERVAL = int(1000 / FPS)  # 毫秒clock = time.clock()
start_time = time.ticks_ms()try:while time.ticks_diff(time.ticks_ms(), start_time) < DURATION * 1000:clock.tick()# 拍摄一帧(JPEG 格式)img = sensor.snapshot()# 获取原始 JPEG 数据jpeg_data = img.compress_to_jpeg()  # 或直接使用 img.bytearray()# 写入文件f.write(jpeg_data)# 可选:显示进度elapsed = time.ticks_diff(time.ticks_ms(), start_time) / 1000print("录制中: %.1fs / %ds, FPS: %.1f" % (elapsed, DURATION, clock.fps()))# 控制帧率time.sleep_ms(max(1, INTERVAL - clock.fps()))print("✅ 视频录制完成:", filename)except Exception as e:print("❌ 录制出错:", e)finally:f.close()

🔧 说明

  • 生成的 .mjpeg 文件可在 VLC、FFmpeg 等工具中播放
  • 每帧为独立 JPEG,拼接成 MJPEG 流

4. 视频回放:从文件读取并显示

4.1 MJPEG 解码与显示(逐帧)

import os
import image
from machine import Timer# 视频文件路径
video_file = "/sd/video/vid_1717000000.mjpeg"# 初始化 TFT 屏幕(见第13章)
# tft = st7789.ST7789(...)def play_video():try:f = open(video_file, "rb")print("开始回放视频...")frame_count = 0start_time = time.ticks_ms()while True:# 尝试读取 JPEG 帧(查找 0xFFD8 和 0xFFD9)data = f.read(1024)if not data:break# 查找 JPEG 起始与结束start = data.find(b'\xFF\xD8')end = data.find(b'\xFF\xD9')if start != -1 and end != -1 and end > start:jpeg_frame = data[start:end+2]# 创建图像对象并显示try:img = image.Image(jpeg_frame)# 缩放显示到 TFT# tft.blit_buffer(img.bytearray(), ...)frame_count += 1except:continueduration = time.ticks_diff(time.ticks_ms(), start_time) / 1000print(f"✅ 回放完成,共 {frame_count} 帧,耗时 {duration:.1f}s")except Exception as e:print("❌ 回放失败:", e)finally:f.close()# 开始回放
play_video()

⚠️ 限制:K230 无硬件 MJPEG 解码,需逐帧解析,效率较低。


5. 实战项目:带状态显示的视频记录仪

# 结合 OLED 或 TFT 显示录制状态import sensor
import lcd  # 假设有 lcd 模块
import time
import ossensor.reset()
sensor.set_pixformat(sensor.JPEG)
sensor.set_framesize(sensor.QVGA)  # 320x240
sensor.set_quality(12)
sensor.skip_frames(time=2000)# 录制函数
def record_video(duration=10):filename = f"/sd/vid_{time.time()}.mjpeg"f = open(filename, "wb")lcd.fill(0)lcd.draw_string(10, 10, "REC", color=(255,0,0))lcd.draw_string(10, 30, filename, color=(255,255,255))start = time.ticks_ms()frame_count = 0while time.ticks_diff(time.ticks_ms(), start) < duration * 1000:img = sensor.snapshot()f.write(img.compress_to_jpeg())frame_count += 1# 更新显示lcd.draw_string(10, 50, f"Frame: {frame_count}", color=(0,255,0))time.sleep_ms(100)f.close()lcd.draw_string(10, 80, "SAVED", color=(0,255,0))

6. 高级技巧与优化

6.1 控制录制大小

MAX_SIZE = 100 * 1024 * 1024  # 100MB
if f.tell() > MAX_SIZE:print("视频达到最大尺寸,停止")break

6.2 使用环形缓冲(覆盖最旧视频)

# 策略:删除最早生成的视频文件
files = os.listdir("/sd/video")
if len(files) > 10:files.sort()os.remove("/sd/video/" + files[0])

6.3 添加时间戳水印

img = sensor.snapshot()
timestamp = "%02d:%02d:%02d" % (time.localtime()[3:6])
img.draw_string(200, 220, timestamp, color=(255,255,255))
f.write(img.compress_to_jpeg())

7. 常见问题与调试

❌ 问题1:视频文件无法播放

解决

  • 使用 VLC 播放器FFmpeg

    ffplay -f mjpeg -i vid_1717000000.mjpeg
    
  • 确保每帧以 0xFFD8 开始、0xFFD9 结束

  • 检查文件是否完整

❌ 问题2:录制帧率低

优化

  • 使用 QVGAQQVGA 分辨率
  • 降低 JPEG 质量(set_quality(20)
  • 使用高速 SD 卡

❌ 问题3:SD 卡写入失败

排查

  • 检查 SPI 接线
  • 确认 SD 卡已格式化为 FAT32
  • 避免频繁打开/关闭文件

8. 性能与存储估算

分辨率质量每帧大小10fps 下每分钟存储
QVGA (320x240)10~8KB~4.8MB
VGA (640x480)10~20KB~12MB
SVGA (800x600)10~35KB~21MB

建议:使用 32GB SD 卡可录制数小时 QVGA 视频。


本章你已掌握

  • K230 视频录制原理(MJPEG 流)
  • 摄像头配置为 JPEG 输出
  • SD 卡存储视频帧
  • 视频回放与显示
  • 性能优化与问题排查

http://www.dtcms.com/a/466560.html

相关文章:

  • 衡水市住房和城乡规划建设网站带着购物系统回到80年代
  • microsoft免费网站那些网站做的非常好看
  • gta5网站正在建设网站基本流程
  • C++学习过程中的一个问题
  • 外贸一般上什么网站动漫制作专业可以升大专吗
  • 构建外贸智能决策大脑
  • 网站建设费税收分类好的做网站的公司
  • Ubuntu 查看内存大小的多种方法
  • 淄博网站外包wordpress设置缓存
  • ProVerif: 形式化证明工具
  • 卷积神经网络CNN(三):三维卷积与多核卷积
  • AI大事记11:从 AlphaGo 到 AlphaGo Zero(下)
  • HTB:Artificial[WriteUP]
  • 网站开发ppt模板免费字体设计
  • openharmony 4.1r ota升级包制作笔记
  • STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
  • 软件设计师——12 案例分析专题-数据流图
  • redis字符串命令
  • 做平面设计的网站wordpress app开发
  • ANSI A1860.1-2017 刨花板地板检测
  • 天津网站seo设计新乡市工程建设信息网
  • iOS 26 崩溃日志解析,新版系统下崩溃获取与诊断策略
  • 成都 网站建设 公司wordpress写模版
  • 经销商城建站网站页头
  • jvm中程序计数器
  • 网站建设代理公司网站评估内容 优帮云
  • 宁波做网站的公司找摄影作品的网站
  • 企业AI化转型的核心抓手:企业智脑如何推动技术与业务深度融合
  • 基于STM32的智能台灯 / WIFI智能台灯 / 智能无极调光台灯
  • uboot重启大法配置流程